26#if defined(__FreeBSD__)
27# include <machine/param.h>
42# define MIN(x, y) ((x) > (y)? (y) : (x))
45#define SEG_ALLOC_SIZE_MAX 32*1024*1024
46#define SEG_ALLOC_SIZE_MIN 2*1024*1024
51} zend_shared_segment_shm;
53static int create_segments(
size_t requested_size, zend_shared_segment_shm ***shared_segments_p,
int *shared_segments_count,
const char **error_in)
56 size_t allocate_size = 0, remaining_bytes = requested_size, seg_allocate_size;
57 int first_segment_id = -1;
58 key_t first_segment_key = -1;
61 zend_shared_segment_shm *shared_segments;
63 seg_allocate_size = SEG_ALLOC_SIZE_MAX;
67 while (requested_size * 2 <= seg_allocate_size && seg_allocate_size > SEG_ALLOC_SIZE_MIN) {
68 seg_allocate_size >>= 1;
71 shmget_flags = IPC_CREAT|SHM_R|SHM_W|IPC_EXCL;
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) {
80 seg_allocate_size >>= 1;
83 if (first_segment_id == -1) {
88 *shared_segments_count = ((requested_size - 1) / seg_allocate_size) + 1;
89 *shared_segments_p = (zend_shared_segment_shm **) calloc(1, (*shared_segments_count) *
sizeof(zend_shared_segment_shm) +
sizeof(
void *) * (*shared_segments_count));
90 if (!*shared_segments_p) {
94 shared_segments = (zend_shared_segment_shm *)((
char *)(*shared_segments_p) +
sizeof(
void *) * (*shared_segments_count));
95 for (i = 0; i < *shared_segments_count; i++) {
96 (*shared_segments_p)[i] = shared_segments + i;
99 remaining_bytes = requested_size;
100 for (i = 0; i < *shared_segments_count; i++) {
101 allocate_size =
MIN(remaining_bytes, seg_allocate_size);
103 shared_segments[i].shm_id = shmget(IPC_PRIVATE, allocate_size, shmget_flags);
105 shared_segments[i].shm_id = first_segment_id;
108 if (shared_segments[i].shm_id == -1) {
112 shared_segments[i].common.p = shmat(shared_segments[i].shm_id,
NULL, 0);
113 if (shared_segments[i].common.p == (
void *)-1) {
115 shmctl(shared_segments[i].shm_id, IPC_RMID, &sds);
118 shmctl(shared_segments[i].shm_id, IPC_RMID, &sds);
120 shared_segments[i].common.pos = 0;
121 shared_segments[i].common.size = allocate_size;
122 remaining_bytes -= allocate_size;
127static int detach_segment(zend_shared_segment_shm *shared_segment)
129 shmdt(shared_segment->common.p);
133static size_t segment_type_size(
void)
135 return sizeof(zend_shared_segment_shm);
struct _zend_shared_segment zend_shared_segment
int(* detach_segment_t)(zend_shared_segment *shared_segment)
int(* create_segments_t)(size_t requested_size, zend_shared_segment ***shared_segments, int *shared_segment_count, const char **error_in)