1 /*
2 +----------------------------------------------------------------------+
3 | Zend OPcache |
4 +----------------------------------------------------------------------+
5 | Copyright (c) The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | https://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Authors: Andi Gutmans <andi@php.net> |
16 | Zeev Suraski <zeev@php.net> |
17 | Stanislav Malyshev <stas@zend.com> |
18 | Dmitry Stogov <dmitry@php.net> |
19 +----------------------------------------------------------------------+
20 */
21
22 #ifndef ZEND_SHARED_ALLOC_H
23 #define ZEND_SHARED_ALLOC_H
24
25 #include "zend.h"
26 #include "ZendAccelerator.h"
27
28 #if defined(__APPLE__) && defined(__MACH__) /* darwin */
29 # ifdef HAVE_SHM_MMAP_POSIX
30 # define USE_SHM_OPEN 1
31 # endif
32 # ifdef HAVE_SHM_MMAP_ANON
33 # define USE_MMAP 1
34 # endif
35 #elif defined(__linux__) || defined(_AIX)
36 # ifdef HAVE_SHM_MMAP_POSIX
37 # define USE_SHM_OPEN 1
38 # endif
39 # ifdef HAVE_SHM_IPC
40 # define USE_SHM 1
41 # endif
42 # ifdef HAVE_SHM_MMAP_ANON
43 # define USE_MMAP 1
44 # endif
45 #elif defined(__sparc) || defined(__sun)
46 # ifdef HAVE_SHM_MMAP_POSIX
47 # define USE_SHM_OPEN 1
48 # endif
49 # ifdef HAVE_SHM_IPC
50 # define USE_SHM 1
51 # endif
52 # if defined(__i386)
53 # ifdef HAVE_SHM_MMAP_ANON
54 # define USE_MMAP 1
55 # endif
56 # endif
57 #else
58 # ifdef HAVE_SHM_MMAP_POSIX
59 # define USE_SHM_OPEN 1
60 # endif
61 # ifdef HAVE_SHM_MMAP_ANON
62 # define USE_MMAP 1
63 # endif
64 # ifdef HAVE_SHM_IPC
65 # define USE_SHM 1
66 # endif
67 #endif
68
69 #define ALLOC_FAILURE 0
70 #define ALLOC_SUCCESS 1
71 #define FAILED_REATTACHED 2
72 #define SUCCESSFULLY_REATTACHED 4
73 #define ALLOC_FAIL_MAPPING 8
74 #define ALLOC_FALLBACK 9
75
76 typedef struct _zend_shared_segment {
77 size_t size;
78 size_t end;
79 size_t pos; /* position for simple stack allocator */
80 void *p;
81 } zend_shared_segment;
82
83 typedef int (*create_segments_t)(size_t requested_size, zend_shared_segment ***shared_segments, int *shared_segment_count, const char **error_in);
84 typedef int (*detach_segment_t)(zend_shared_segment *shared_segment);
85
86 typedef struct {
87 create_segments_t create_segments;
88 detach_segment_t detach_segment;
89 size_t (*segment_type_size)(void);
90 } zend_shared_memory_handlers;
91
92 typedef struct _handler_entry {
93 const char *name;
94 const zend_shared_memory_handlers *handler;
95 } zend_shared_memory_handler_entry;
96
97 typedef struct _zend_shared_memory_state {
98 size_t *positions; /* current positions for each segment */
99 size_t shared_free; /* amount of free shared memory */
100 } zend_shared_memory_state;
101
102 typedef struct _zend_smm_shared_globals {
103 /* Shared Memory Manager */
104 zend_shared_segment **shared_segments;
105 /* Number of allocated shared segments */
106 int shared_segments_count;
107 /* Amount of free shared memory */
108 size_t shared_free;
109 /* Amount of shared memory allocated by garbage */
110 size_t wasted_shared_memory;
111 /* No more shared memory flag */
112 bool memory_exhausted;
113 /* Saved Shared Allocator State */
114 zend_shared_memory_state shared_memory_state;
115 /* Pointer to the application's shared data structures */
116 void *app_shared_globals;
117 /* Reserved shared memory */
118 void *reserved;
119 size_t reserved_size;
120 } zend_smm_shared_globals;
121
122 extern zend_smm_shared_globals *smm_shared_globals;
123
124 #define ZSMMG(element) (smm_shared_globals->element)
125
126 #define SHARED_ALLOC_REATTACHED (SUCCESS+1)
127
128 BEGIN_EXTERN_C()
129
130 int zend_shared_alloc_startup(size_t requested_size, size_t reserved_size);
131 void zend_shared_alloc_shutdown(void);
132
133 /* allocate shared memory block */
134 void *zend_shared_alloc(size_t size);
135
136 /**
137 * Wrapper for zend_shared_alloc() which aligns at 64-byte boundary if
138 * AVX or SSE2 are used.
139 */
zend_shared_alloc_aligned(size_t size)140 static inline void *zend_shared_alloc_aligned(size_t size) {
141 #if defined(__AVX__) || defined(__SSE2__)
142 /* Align to 64-byte boundary */
143 void *p = zend_shared_alloc(size + 64);
144 return (void *)(((uintptr_t)p + 63L) & ~63L);
145 #else
146 return zend_shared_alloc(size);
147 #endif
148 }
149
150 /* copy into shared memory */
151 void *zend_shared_memdup_get_put_free(void *source, size_t size);
152 void *zend_shared_memdup_put_free(void *source, size_t size);
153 void *zend_shared_memdup_free(void *source, size_t size);
154 void *zend_shared_memdup_get_put(void *source, size_t size);
155 void *zend_shared_memdup_put(void *source, size_t size);
156 void *zend_shared_memdup(void *source, size_t size);
157
158 int zend_shared_memdup_size(void *p, size_t size);
159
160 bool zend_accel_in_shm(void *ptr);
161
162 typedef union _align_test {
163 void *ptr;
164 double dbl;
165 zend_long lng;
166 } align_test;
167
168 #if ZEND_GCC_VERSION >= 2000
169 # define PLATFORM_ALIGNMENT (__alignof__(align_test) < 8 ? 8 : __alignof__(align_test))
170 #else
171 # define PLATFORM_ALIGNMENT (sizeof(align_test))
172 #endif
173
174 #define ZEND_ALIGNED_SIZE(size) \
175 ZEND_MM_ALIGNED_SIZE_EX(size, PLATFORM_ALIGNMENT)
176
177 /* exclusive locking */
178 void zend_shared_alloc_lock(void);
179 void zend_shared_alloc_unlock(void); /* returns the allocated size during lock..unlock */
180 void zend_shared_alloc_safe_unlock(void);
181
182 /* old/new mapping functions */
183 void zend_shared_alloc_init_xlat_table(void);
184 void zend_shared_alloc_destroy_xlat_table(void);
185 void zend_shared_alloc_clear_xlat_table(void);
186 uint32_t zend_shared_alloc_checkpoint_xlat_table(void);
187 void zend_shared_alloc_restore_xlat_table(uint32_t checkpoint);
188 void zend_shared_alloc_register_xlat_entry(const void *key, const void *value);
189 void *zend_shared_alloc_get_xlat_entry(const void *key);
190
191 size_t zend_shared_alloc_get_free_memory(void);
192 void zend_shared_alloc_save_state(void);
193 void zend_shared_alloc_restore_state(void);
194 const char *zend_accel_get_shared_model(void);
195
196 /**
197 * Memory write protection
198 *
199 * @param protected true to protect shared memory (read-only), false
200 * to unprotect shared memory (writable)
201 */
202 void zend_accel_shared_protect(bool protected);
203
204 #ifdef USE_MMAP
205 extern const zend_shared_memory_handlers zend_alloc_mmap_handlers;
206 #endif
207
208 #ifdef USE_SHM
209 extern const zend_shared_memory_handlers zend_alloc_shm_handlers;
210 #endif
211
212 #ifdef USE_SHM_OPEN
213 extern const zend_shared_memory_handlers zend_alloc_posix_handlers;
214 #endif
215
216 #ifdef ZEND_WIN32
217 extern const zend_shared_memory_handlers zend_alloc_win32_handlers;
218 void zend_shared_alloc_create_lock(void);
219 void zend_shared_alloc_lock_win32(void);
220 void zend_shared_alloc_unlock_win32(void);
221 #endif
222
223 END_EXTERN_C()
224
225 #endif /* ZEND_SHARED_ALLOC_H */
226