Skip to content

Commit 2e0ca47

Browse files
committedOct 9, 2023
opcache posix creating special shared segments for FreeBSD 13 and above.
From this release, it is permitted to create shared memory blocks tagged as large for faster accesses for a size compatible with otherwise we fallback to a classic creation. Close GH-8037
1 parent 76a773b commit 2e0ca47

File tree

3 files changed

+44
-2
lines changed

3 files changed

+44
-2
lines changed
 

‎NEWS

+3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ DOM:
1313
Intl:
1414
. Added IntlDateFormatter::PATTERN constant. (David Carlier)
1515

16+
Opcache:
17+
. Added large shared segments support for FreeBSD. (David Carlier)
18+
1619
PGSQL:
1720
. Added the possibility to have no conditions for pg_select. (OmarEmaraDev)
1821

‎ext/opcache/config.m4

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ if test "$PHP_OPCACHE" != "no"; then
8888
PHP_SUBST(DASM_ARCH)
8989
fi
9090

91-
AC_CHECK_FUNCS([mprotect memfd_create])
91+
AC_CHECK_FUNCS([mprotect memfd_create shm_create_largepage])
9292

9393
AC_MSG_CHECKING(for sysvipc shared memory support)
9494
AC_RUN_IFELSE([AC_LANG_SOURCE([[

‎ext/opcache/shared_alloc_posix.c

+40-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,33 @@ static int create_segments(size_t requested_size, zend_shared_segment_posix ***s
4040
{
4141
zend_shared_segment_posix *shared_segment;
4242
char shared_segment_name[sizeof("/ZendAccelerator.") + 20];
43+
int shared_segment_flags = O_RDWR|O_CREAT|O_TRUNC;
44+
mode_t shared_segment_mode = 0600;
45+
46+
#if defined(HAVE_SHM_CREATE_LARGEPAGE)
47+
/**
48+
* architectures have 3 entries max and we are interested
49+
* from the second offset minimum to be worthy creating
50+
* a special shared segment tagged as 'large'.
51+
* only then amd64/i386/arm64 and perharps risc64*
52+
* archs are on interest here.
53+
*/
54+
size_t i, shared_segment_sizes = 0, shared_segment_lg_index = 0;
55+
size_t shared_segment_sindexes[3] = {0};
56+
const size_t entries = sizeof(shared_segment_sindexes) / sizeof(shared_segment_sindexes[0]);
57+
58+
shared_segment_sizes = getpagesizes(shared_segment_sindexes, entries);
59+
60+
if (shared_segment_sizes > 0) {
61+
for (i = shared_segment_sizes - 1; i >= 0; i --) {
62+
if (shared_segment_sindexes[i] != 0 &&
63+
!(requested_size % shared_segment_sindexes[i])) {
64+
shared_segment_lg_index = i;
65+
break;
66+
}
67+
}
68+
}
69+
#endif
4370

4471
*shared_segments_count = 1;
4572
*shared_segments_p = (zend_shared_segment_posix **) calloc(1, sizeof(zend_shared_segment_posix) + sizeof(void *));
@@ -51,12 +78,24 @@ static int create_segments(size_t requested_size, zend_shared_segment_posix ***s
5178
(*shared_segments_p)[0] = shared_segment;
5279

5380
sprintf(shared_segment_name, "/ZendAccelerator.%d", getpid());
54-
shared_segment->shm_fd = shm_open(shared_segment_name, O_RDWR|O_CREAT|O_TRUNC, 0600);
81+
#if defined(HAVE_SHM_CREATE_LARGEPAGE)
82+
if (shared_segment_lg_index > 0) {
83+
shared_segment->shm_fd = shm_create_largepage(shared_segment_name, shared_segment_flags, shared_segment_lg_index, SHM_LARGEPAGE_ALLOC_DEFAULT, shared_segment_mode);
84+
if (shared_segment->shm_fd != -1) {
85+
goto truncate_segment;
86+
}
87+
}
88+
#endif
89+
90+
shared_segment->shm_fd = shm_open(shared_segment_name, shared_segment_flags, shared_segment_mode);
5591
if (shared_segment->shm_fd == -1) {
5692
*error_in = "shm_open";
5793
return ALLOC_FAILURE;
5894
}
5995

96+
#if defined(HAVE_SHM_CREATE_LARGEPAGE)
97+
truncate_segment:
98+
#endif
6099
if (ftruncate(shared_segment->shm_fd, requested_size) != 0) {
61100
*error_in = "ftruncate";
62101
shm_unlink(shared_segment_name);

0 commit comments

Comments
 (0)