Code cleanup preparing for more GC scan functions.
[hiphop-php.git] / hphp / runtime / ext_zend_compat / php-src / TSRM / TSRM.h
blobd3b8f67a8b92033ae671953f8ae4f31f9d68086c
1 /*
2 +----------------------------------------------------------------------+
3 | Thread Safe Resource Manager |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1999-2011, Andi Gutmans, Sascha Schumann, Zeev Suraski |
6 | This source file is subject to the TSRM license, that is bundled |
7 | with this package in the file LICENSE |
8 +----------------------------------------------------------------------+
9 | Authors: Zeev Suraski <zeev@zend.com> |
10 +----------------------------------------------------------------------+
13 #ifndef TSRM_H
14 #define TSRM_H
16 #if !defined(__CYGWIN__) && defined(WIN32)
17 # define TSRM_WIN32
18 # include "tsrm_config.w32.h"
19 #else
20 # include <tsrm_config.h>
21 #endif
23 #ifdef TSRM_WIN32
24 # ifdef TSRM_EXPORTS
25 # define TSRM_API __declspec(dllexport)
26 # else
27 # define TSRM_API __declspec(dllimport)
28 # endif
29 #elif defined(__GNUC__) && __GNUC__ >= 4
30 # define TSRM_API __attribute__ ((__visibility__("default")))
31 #else
32 # define TSRM_API
33 #endif
35 #ifdef _WIN64
36 typedef __int64 tsrm_intptr_t;
37 typedef unsigned __int64 tsrm_uintptr_t;
38 #else
39 typedef long tsrm_intptr_t;
40 typedef unsigned long tsrm_uintptr_t;
41 #endif
43 /* Only compile multi-threading functions if we're in ZTS mode */
44 #ifdef ZTS
46 #ifdef TSRM_WIN32
47 # ifndef TSRM_INCLUDE_FULL_WINDOWS_HEADERS
48 # define WIN32_LEAN_AND_MEAN
49 # endif
50 # include <windows.h>
51 # include <shellapi.h>
52 #elif defined(GNUPTH)
53 # include <pth.h>
54 #elif defined(PTHREADS)
55 # include <pthread.h>
56 #elif defined(TSRM_ST)
57 # include <st.h>
58 #elif defined(BETHREADS)
59 #include <kernel/OS.h>
60 #include <TLS.h>
61 #endif
63 typedef int ts_rsrc_id;
65 /* Define THREAD_T and MUTEX_T */
66 #ifdef TSRM_WIN32
67 # define THREAD_T DWORD
68 # define MUTEX_T CRITICAL_SECTION *
69 #elif defined(GNUPTH)
70 # define THREAD_T pth_t
71 # define MUTEX_T pth_mutex_t *
72 #elif defined(PTHREADS)
73 # define THREAD_T pthread_t
74 # define MUTEX_T pthread_mutex_t *
75 #elif defined(NSAPI)
76 # define THREAD_T SYS_THREAD
77 # define MUTEX_T CRITICAL
78 #elif defined(PI3WEB)
79 # define THREAD_T PIThread *
80 # define MUTEX_T PISync *
81 #elif defined(TSRM_ST)
82 # define THREAD_T st_thread_t
83 # define MUTEX_T st_mutex_t
84 #elif defined(BETHREADS)
85 # define THREAD_T thread_id
86 typedef struct {
87 sem_id sem;
88 int32 ben;
89 } beos_ben;
90 # define MUTEX_T beos_ben *
91 #endif
93 #ifdef HAVE_SIGNAL_H
94 #include <signal.h>
95 #endif
97 typedef void (*ts_allocate_ctor)(void *, void ***);
98 typedef void (*ts_allocate_dtor)(void *, void ***);
100 #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
102 #ifndef HHVM
103 #ifdef __cplusplus
104 extern "C" {
105 #endif
106 #endif
108 /* startup/shutdown */
109 TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, char *debug_filename);
110 TSRM_API void tsrm_shutdown(void);
112 /* allocates a new thread-safe-resource id */
113 TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor);
115 #define TSRM_SHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)+1)
116 #define TSRM_UNSHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)-1)
118 #ifdef HHVM
120 #include <vector>
121 #include <string>
122 #include <assert.h>
123 #if (defined (__GNUC__) && __GNUC__ > 2 ) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX)
124 # define TSRM_UNEXPECTED(condition) __builtin_expect(condition, 0)
125 #else
126 # define TSRM_UNEXPECTED(condition) (condition)
127 #endif
129 #include "hphp/util/thread-local.h"
130 namespace HPHP {
131 typedef std::vector<void*> TSRMStorageVector;
132 extern DECLARE_THREAD_LOCAL(TSRMStorageVector, tsrm_thread_resources);
133 void * ts_init_resource(int id);
135 static inline
136 void* ts_resource_from_vector(const TSRMStorageVector & vec, ts_rsrc_id id) {
137 void * ret;
138 assert(id != 0);
139 if (TSRM_UNEXPECTED(vec.size() <= TSRM_UNSHUFFLE_RSRC_ID(id))) {
140 return ts_init_resource(id);
141 } else {
142 ret = vec[TSRM_UNSHUFFLE_RSRC_ID(id)];
143 if (TSRM_UNEXPECTED(ret == nullptr)) {
144 return ts_init_resource(id);
145 } else {
146 return ret;
150 } // namespace HPHP
152 static inline void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id) {
153 assert(th_id == NULL); // unimplemented
154 return HPHP::ts_resource_from_vector(*HPHP::tsrm_thread_resources, id);
157 #else
158 /* fetches the requested resource for the current thread */
159 TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id);
160 #endif
161 #define ts_resource(id) ts_resource_ex(id, NULL)
163 /* frees all resources allocated for the current thread */
164 TSRM_API void ts_free_thread(void);
166 /* frees all resources allocated for all threads except current */
167 void ts_free_worker_threads(void);
169 /* deallocates all occurrences of a given id */
170 TSRM_API void ts_free_id(ts_rsrc_id id);
173 /* Debug support */
174 #define TSRM_ERROR_LEVEL_ERROR 1
175 #define TSRM_ERROR_LEVEL_CORE 2
176 #define TSRM_ERROR_LEVEL_INFO 3
178 typedef void (*tsrm_thread_begin_func_t)(THREAD_T thread_id, void ***tsrm_ls);
179 typedef void (*tsrm_thread_end_func_t)(THREAD_T thread_id, void ***tsrm_ls);
182 TSRM_API int tsrm_error(int level, const char *format, ...);
183 TSRM_API void tsrm_error_set(int level, char *debug_filename);
185 /* utility functions */
186 TSRM_API THREAD_T tsrm_thread_id(void);
187 TSRM_API MUTEX_T tsrm_mutex_alloc(void);
188 TSRM_API void tsrm_mutex_free(MUTEX_T mutexp);
189 TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp);
190 TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp);
191 #ifdef HAVE_SIGPROCMASK
192 TSRM_API int tsrm_sigmask(int how, const sigset_t *set, sigset_t *oldset);
193 #endif
195 TSRM_API void *tsrm_set_new_thread_begin_handler(tsrm_thread_begin_func_t new_thread_begin_handler);
196 TSRM_API void *tsrm_set_new_thread_end_handler(tsrm_thread_end_func_t new_thread_end_handler);
198 /* these 3 APIs should only be used by people that fully understand the threading model
199 * used by PHP/Zend and the selected SAPI. */
200 TSRM_API void *tsrm_new_interpreter_context(void);
201 TSRM_API void *tsrm_set_interpreter_context(void *new_ctx);
202 TSRM_API void tsrm_free_interpreter_context(void *context);
204 #ifdef HHVM
206 #define TSRMLS_FETCH() void ***tsrm_ls = reinterpret_cast<void***>(HPHP::tsrm_thread_resources.get())
207 #define TSRMLS_FETCH_FROM_CTX(ctx) void ***tsrm_ls = (void ***) ctx
208 #define TSRMLS_SET_CTX(ctx) ctx = (void ***) tsrm_ls
209 #define TSRMG(id, type, element) \
210 (static_cast<type>(HPHP::ts_resource_from_vector( \
211 *reinterpret_cast<HPHP::TSRMStorageVector*>(tsrm_ls), id))->element)
212 #else /*non-HHVM*/
214 #define TSRMLS_FETCH() void ***tsrm_ls = (void ***) ts_resource_ex(0, NULL)
215 #define TSRMLS_FETCH_FROM_CTX(ctx) void ***tsrm_ls = (void ***) ctx
216 #define TSRMLS_SET_CTX(ctx) ctx = (void ***) tsrm_ls
217 #define TSRMG(id, type, element) (((type) (*((void ***) tsrm_ls))[TSRM_UNSHUFFLE_RSRC_ID(id)])->element)
219 #endif
221 #define TSRMLS_D void ***tsrm_ls
222 #define TSRMLS_DC , TSRMLS_D
223 #define TSRMLS_C tsrm_ls
224 #define TSRMLS_CC , TSRMLS_C
226 #ifndef HHVM
227 #ifdef __cplusplus
229 #endif
230 #endif
232 #else /* non ZTS */
234 #define TSRMLS_FETCH()
235 #define TSRMLS_FETCH_FROM_CTX(ctx)
236 #define TSRMLS_SET_CTX(ctx)
237 #define TSRMLS_D void
238 #define TSRMLS_DC
239 #define TSRMLS_C
240 #define TSRMLS_CC
242 #endif /* ZTS */
244 #endif /* TSRM_H */