Skip to content

Commit d29a4a9

Browse files
committed
Improve shared_alloc_shm.c strategy
Try allocating a contiguous buffer first, and only then use segmentation. Segmentation breaks the JIT, so a contiguous buffer is preferable.
1 parent d2ca471 commit d29a4a9

File tree

1 file changed

+22
-21
lines changed

1 file changed

+22
-21
lines changed

ext/opcache/shared_alloc_shm.c

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
# define MIN(x, y) ((x) > (y)? (y) : (x))
4343
#endif
4444

45-
#define SEG_ALLOC_SIZE_MAX 64*1024*1024 /* 64MB to match ZEND_JIT_DEFAULT_BUFFER_SIZE */
4645
#define SEG_ALLOC_SIZE_MIN 2*1024*1024
4746

4847
typedef struct {
@@ -53,36 +52,38 @@ typedef struct {
5352
static int create_segments(size_t requested_size, zend_shared_segment_shm ***shared_segments_p, int *shared_segments_count, const char **error_in)
5453
{
5554
int i;
56-
size_t allocate_size = 0, remaining_bytes = requested_size, seg_allocate_size;
55+
size_t allocate_size = 0, remaining_bytes, seg_allocate_size;
5756
int first_segment_id = -1;
5857
key_t first_segment_key = -1;
5958
struct shmid_ds sds;
6059
int shmget_flags;
6160
zend_shared_segment_shm *shared_segments;
6261

63-
seg_allocate_size = SEG_ALLOC_SIZE_MAX;
64-
/* determine segment size we _really_ need:
65-
* no more than to include requested_size
66-
*/
67-
while (requested_size * 2 <= seg_allocate_size && seg_allocate_size > SEG_ALLOC_SIZE_MIN) {
68-
seg_allocate_size >>= 1;
69-
}
70-
7162
shmget_flags = IPC_CREAT|SHM_R|SHM_W|IPC_EXCL;
7263

73-
/* try allocating this much, if not - try shrinking */
74-
while (seg_allocate_size >= SEG_ALLOC_SIZE_MIN) {
75-
allocate_size = MIN(requested_size, seg_allocate_size);
76-
first_segment_id = shmget(first_segment_key, allocate_size, shmget_flags);
77-
if (first_segment_id != -1) {
78-
break;
64+
/* Try contiguous allocation first. */
65+
seg_allocate_size = requested_size;
66+
first_segment_id = shmget(first_segment_key, seg_allocate_size, shmget_flags);
67+
if (UNEXPECTED(first_segment_id == -1)) {
68+
/* Search for power of n^2 < requested_size. */
69+
seg_allocate_size = 1024 * 1024;
70+
while (seg_allocate_size < requested_size / 2) {
71+
seg_allocate_size *= 2;
7972
}
80-
seg_allocate_size >>= 1; /* shrink the allocated block */
81-
}
8273

83-
if (first_segment_id == -1) {
84-
*error_in = "shmget";
85-
return ALLOC_FAILURE;
74+
/* try allocating this much, if not - try shrinking */
75+
while (seg_allocate_size >= SEG_ALLOC_SIZE_MIN) {
76+
first_segment_id = shmget(first_segment_key, seg_allocate_size, shmget_flags);
77+
if (first_segment_id != -1) {
78+
break;
79+
}
80+
seg_allocate_size >>= 1; /* shrink the allocated block */
81+
}
82+
83+
if (first_segment_id == -1) {
84+
*error_in = "shmget";
85+
return ALLOC_FAILURE;
86+
}
8687
}
8788

8889
*shared_segments_count = ((requested_size - 1) / seg_allocate_size) + 1;

0 commit comments

Comments
 (0)