xref: /php-src/ext/opcache/zend_shared_alloc.h (revision e0ca4dca)
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