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
4847typedef struct {
@@ -53,36 +52,38 @@ typedef struct {
5352static 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