TSRM.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  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@php.net> |
  10. +----------------------------------------------------------------------+
  11. */
  12. #ifndef TSRM_H
  13. #define TSRM_H
  14. #if !defined(__CYGWIN__) && defined(WIN32)
  15. # define TSRM_WIN32
  16. # include "Zend/zend_config.w32.h"
  17. #else
  18. # include "main/php_config.h"
  19. #endif
  20. #include "main/php_stdint.h"
  21. #ifdef TSRM_WIN32
  22. # ifdef TSRM_EXPORTS
  23. # define TSRM_API __declspec(dllexport)
  24. # else
  25. # define TSRM_API __declspec(dllimport)
  26. # endif
  27. #elif defined(__GNUC__) && __GNUC__ >= 4
  28. # define TSRM_API __attribute__ ((visibility("default")))
  29. #else
  30. # define TSRM_API
  31. #endif
  32. typedef intptr_t tsrm_intptr_t;
  33. typedef uintptr_t tsrm_uintptr_t;
  34. /* Only compile multi-threading functions if we're in ZTS mode */
  35. #ifdef ZTS
  36. #ifdef TSRM_WIN32
  37. # ifndef TSRM_INCLUDE_FULL_WINDOWS_HEADERS
  38. # define WIN32_LEAN_AND_MEAN
  39. # endif
  40. #else
  41. # include <pthread.h>
  42. #endif
  43. #if SIZEOF_SIZE_T == 4
  44. # define TSRM_ALIGNED_SIZE(size) \
  45. (((size) + INT32_C(15)) & ~INT32_C(15))
  46. #else
  47. # define TSRM_ALIGNED_SIZE(size) \
  48. (((size) + INT64_C(15)) & ~INT64_C(15))
  49. #endif
  50. typedef int ts_rsrc_id;
  51. /* Define THREAD_T and MUTEX_T */
  52. #ifdef TSRM_WIN32
  53. # define THREAD_T DWORD
  54. # define MUTEX_T CRITICAL_SECTION *
  55. #else
  56. # define THREAD_T pthread_t
  57. # define MUTEX_T pthread_mutex_t *
  58. #endif
  59. #include <signal.h>
  60. typedef void (*ts_allocate_ctor)(void *);
  61. typedef void (*ts_allocate_dtor)(void *);
  62. #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
  63. #ifdef __cplusplus
  64. extern "C" {
  65. #endif
  66. /* startup/shutdown */
  67. TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, const char *debug_filename);
  68. TSRM_API void tsrm_shutdown(void);
  69. /* environ lock API */
  70. TSRM_API void tsrm_env_lock(void);
  71. TSRM_API void tsrm_env_unlock(void);
  72. /* allocates a new thread-safe-resource id */
  73. TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor);
  74. /* Fast resource in reserved (pre-allocated) space */
  75. TSRM_API void tsrm_reserve(size_t size);
  76. TSRM_API ts_rsrc_id ts_allocate_fast_id(ts_rsrc_id *rsrc_id, size_t *offset, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor);
  77. /* fetches the requested resource for the current thread */
  78. TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id);
  79. #define ts_resource(id) ts_resource_ex(id, NULL)
  80. /* frees all resources allocated for the current thread */
  81. TSRM_API void ts_free_thread(void);
  82. /* deallocates all occurrences of a given id */
  83. TSRM_API void ts_free_id(ts_rsrc_id id);
  84. /* Debug support */
  85. #define TSRM_ERROR_LEVEL_ERROR 1
  86. #define TSRM_ERROR_LEVEL_CORE 2
  87. #define TSRM_ERROR_LEVEL_INFO 3
  88. typedef void (*tsrm_thread_begin_func_t)(THREAD_T thread_id);
  89. typedef void (*tsrm_thread_end_func_t)(THREAD_T thread_id);
  90. typedef void (*tsrm_shutdown_func_t)(void);
  91. TSRM_API int tsrm_error(int level, const char *format, ...);
  92. TSRM_API void tsrm_error_set(int level, const char *debug_filename);
  93. /* utility functions */
  94. TSRM_API THREAD_T tsrm_thread_id(void);
  95. TSRM_API MUTEX_T tsrm_mutex_alloc(void);
  96. TSRM_API void tsrm_mutex_free(MUTEX_T mutexp);
  97. TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp);
  98. TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp);
  99. #ifdef HAVE_SIGPROCMASK
  100. TSRM_API int tsrm_sigmask(int how, const sigset_t *set, sigset_t *oldset);
  101. #endif
  102. TSRM_API void *tsrm_set_new_thread_begin_handler(tsrm_thread_begin_func_t new_thread_begin_handler);
  103. TSRM_API void *tsrm_set_new_thread_end_handler(tsrm_thread_end_func_t new_thread_end_handler);
  104. TSRM_API void *tsrm_set_shutdown_handler(tsrm_shutdown_func_t shutdown_handler);
  105. TSRM_API void *tsrm_get_ls_cache(void);
  106. TSRM_API size_t tsrm_get_ls_cache_tcb_offset(void);
  107. TSRM_API uint8_t tsrm_is_main_thread(void);
  108. TSRM_API uint8_t tsrm_is_shutdown(void);
  109. TSRM_API const char *tsrm_api_name(void);
  110. #ifdef TSRM_WIN32
  111. # define TSRM_TLS __declspec(thread)
  112. #else
  113. # define TSRM_TLS __thread
  114. #endif
  115. #ifndef __has_attribute
  116. # define __has_attribute(x) 0
  117. #endif
  118. #if !__has_attribute(tls_model) || defined(__FreeBSD__) || defined(__MUSL__) || defined(__HAIKU__)
  119. # define TSRM_TLS_MODEL_ATTR
  120. #elif __PIC__
  121. # define TSRM_TLS_MODEL_ATTR __attribute__((tls_model("initial-exec")))
  122. #else
  123. # define TSRM_TLS_MODEL_ATTR __attribute__((tls_model("local-exec")))
  124. #endif
  125. #define TSRM_SHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)+1)
  126. #define TSRM_UNSHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)-1)
  127. #define TSRMG(id, type, element) (TSRMG_BULK(id, type)->element)
  128. #define TSRMG_BULK(id, type) ((type) (*((void ***) tsrm_get_ls_cache()))[TSRM_UNSHUFFLE_RSRC_ID(id)])
  129. #define TSRMG_FAST(offset, type, element) (TSRMG_FAST_BULK(offset, type)->element)
  130. #define TSRMG_FAST_BULK(offset, type) ((type) (((char*) tsrm_get_ls_cache())+(offset)))
  131. #define TSRMG_STATIC(id, type, element) (TSRMG_BULK_STATIC(id, type)->element)
  132. #define TSRMG_BULK_STATIC(id, type) ((type) (*((void ***) TSRMLS_CACHE))[TSRM_UNSHUFFLE_RSRC_ID(id)])
  133. #define TSRMG_FAST_STATIC(offset, type, element) (TSRMG_FAST_BULK_STATIC(offset, type)->element)
  134. #define TSRMG_FAST_BULK_STATIC(offset, type) ((type) (((char*) TSRMLS_CACHE)+(offset)))
  135. #define TSRMLS_MAIN_CACHE_EXTERN() extern TSRM_TLS void *TSRMLS_CACHE TSRM_TLS_MODEL_ATTR;
  136. #define TSRMLS_MAIN_CACHE_DEFINE() TSRM_TLS void *TSRMLS_CACHE TSRM_TLS_MODEL_ATTR = NULL;
  137. #define TSRMLS_CACHE_EXTERN() extern TSRM_TLS void *TSRMLS_CACHE;
  138. #define TSRMLS_CACHE_DEFINE() TSRM_TLS void *TSRMLS_CACHE = NULL;
  139. #define TSRMLS_CACHE_UPDATE() TSRMLS_CACHE = tsrm_get_ls_cache()
  140. #define TSRMLS_CACHE _tsrm_ls_cache
  141. #ifdef __cplusplus
  142. }
  143. #endif
  144. #else /* non ZTS */
  145. #define tsrm_env_lock()
  146. #define tsrm_env_unlock()
  147. #define TSRMG_STATIC(id, type, element)
  148. #define TSRMLS_MAIN_CACHE_EXTERN()
  149. #define TSRMLS_MAIN_CACHE_DEFINE()
  150. #define TSRMLS_CACHE_EXTERN()
  151. #define TSRMLS_CACHE_DEFINE()
  152. #define TSRMLS_CACHE_UPDATE()
  153. #define TSRMLS_CACHE
  154. #define TSRM_TLS
  155. #endif /* ZTS */
  156. #endif /* TSRM_H */