Skip to content

Add zend_getpagesize() and reuse it in accelerator and fiber #7057

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions Zend/zend.c
Original file line number Diff line number Diff line change
Expand Up @@ -1207,6 +1207,21 @@ ZEND_API ZEND_COLD ZEND_NORETURN void _zend_bailout(const char *filename, uint32
/* }}} */
END_EXTERN_C()

ZEND_API size_t zend_get_page_size(void)
{
#ifdef _WIN32
SYSTEM_INFO system_info;
GetSystemInfo(&system_info);
return system_info.dwPageSize;
#elif defined(__FreeBSD__)
/* This returns the value obtained from
* the auxv vector, avoiding a syscall. */
return getpagesize();
#else
return (size_t) sysconf(_SC_PAGESIZE);
#endif
}

ZEND_API void zend_append_version_info(const zend_extension *extension) /* {{{ */
{
char *new_info;
Expand Down
1 change: 1 addition & 0 deletions Zend/zend.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ zend_result zend_post_startup(void);
void zend_set_utility_values(zend_utility_values *utility_values);

ZEND_API ZEND_COLD ZEND_NORETURN void _zend_bailout(const char *filename, uint32_t lineno);
ZEND_API size_t zend_get_page_size(void);

ZEND_API size_t zend_vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap);
ZEND_API size_t zend_spprintf(char **message, size_t max_len, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 3, 4);
Expand Down
20 changes: 9 additions & 11 deletions Zend/zend_fibers.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,27 +90,25 @@ extern transfer_t jump_fcontext(fcontext_t to, void *vp);
# define ZEND_FIBER_STACK_FLAGS (MAP_PRIVATE | MAP_ANON)
#endif



static size_t zend_fiber_page_size()
static size_t zend_fiber_get_page_size(void)
{
#if _POSIX_MAPPED_FILES
static size_t page_size;
static size_t page_size = 0;

if (!page_size) {
page_size = sysconf(_SC_PAGESIZE);
page_size = zend_get_page_size();
if (!page_size || (page_size & (page_size - 1))) {
/* anyway, we have to return a valid result */
page_size = ZEND_FIBER_DEFAULT_PAGE_SIZE;
}
}

return page_size;
#else
return ZEND_FIBER_DEFAULT_PAGE_SIZE;
#endif
}

static bool zend_fiber_stack_allocate(zend_fiber_stack *stack, size_t size)
{
void *pointer;
const size_t page_size = zend_fiber_page_size();
const size_t page_size = zend_fiber_get_page_size();

ZEND_ASSERT(size >= page_size + ZEND_FIBER_GUARD_PAGES * page_size);

Expand Down Expand Up @@ -167,7 +165,7 @@ static void zend_fiber_stack_free(zend_fiber_stack *stack)
VALGRIND_STACK_DEREGISTER(stack->valgrind);
#endif

const size_t page_size = zend_fiber_page_size();
const size_t page_size = zend_fiber_get_page_size();

void *pointer = (void *) ((uintptr_t) stack->pointer - ZEND_FIBER_GUARD_PAGES * page_size);

Expand Down
10 changes: 2 additions & 8 deletions ext/opcache/ZendAccelerator.c
Original file line number Diff line number Diff line change
Expand Up @@ -3171,14 +3171,8 @@ static zend_result accel_post_startup(void)
&& zend_jit_check_support() == SUCCESS) {
size_t page_size;

# ifdef _WIN32
SYSTEM_INFO system_info;
GetSystemInfo(&system_info);
page_size = system_info.dwPageSize;
# else
page_size = getpagesize();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like we're unconditionally using getpagesize() here. Why does the new code limit its use to only FreeBSD?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Linux manual recommends using sysconf(_SC_PAGESIZE) instead of getpagesize() for portability.
The code is referenced from https://github.com/jemalloc/jemalloc/blob/master/src/pages.c#L417
The comment shows the reason for it, it can avoid a useless syscall on FreeBSD.

# endif
if (!page_size || (page_size & (page_size - 1))) {
page_size = zend_get_page_size();
if (!page_size && (page_size & (page_size - 1))) {
zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Failure to initialize shared memory structures - can't get page size.");
abort();
}
Expand Down