PageRenderTime 54ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/sapi/fpm/fpm/fpm_scoreboard.c

https://bitbucket.org/luobailiang/php-src
C | 328 lines | 255 code | 56 blank | 17 comment | 62 complexity | 6b5d63e0de3851008bf46fcb27eac6f5 MD5 | raw file
  1. /* $Id: fpm_status.c 312399 2011-06-23 08:03:52Z fat $ */
  2. /* (c) 2009 Jerome Loyet */
  3. #include "php.h"
  4. #include "SAPI.h"
  5. #include <stdio.h>
  6. #include <time.h>
  7. #include "fpm_config.h"
  8. #include "fpm_scoreboard.h"
  9. #include "fpm_shm.h"
  10. #include "fpm_sockets.h"
  11. #include "fpm_worker_pool.h"
  12. #include "fpm_clock.h"
  13. #include "zlog.h"
  14. static struct fpm_scoreboard_s *fpm_scoreboard = NULL;
  15. static int fpm_scoreboard_i = -1;
  16. #ifdef HAVE_TIMES
  17. static float fpm_scoreboard_tick;
  18. #endif
  19. int fpm_scoreboard_init_main() /* {{{ */
  20. {
  21. struct fpm_worker_pool_s *wp;
  22. int i;
  23. #ifdef HAVE_TIMES
  24. #if (defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK))
  25. fpm_scoreboard_tick = sysconf(_SC_CLK_TCK);
  26. #else /* _SC_CLK_TCK */
  27. #ifdef HZ
  28. fpm_scoreboard_tick = HZ;
  29. #else /* HZ */
  30. fpm_scoreboard_tick = 100;
  31. #endif /* HZ */
  32. #endif /* _SC_CLK_TCK */
  33. zlog(ZLOG_DEBUG, "got clock tick '%.0f'", fpm_scoreboard_tick);
  34. #endif /* HAVE_TIMES */
  35. for (wp = fpm_worker_all_pools; wp; wp = wp->next) {
  36. if (wp->config->pm_max_children < 1) {
  37. zlog(ZLOG_ERROR, "[pool %s] Unable to create scoreboard SHM because max_client is not set", wp->config->name);
  38. return -1;
  39. }
  40. if (wp->scoreboard) {
  41. zlog(ZLOG_ERROR, "[pool %s] Unable to create scoreboard SHM because it already exists", wp->config->name);
  42. return -1;
  43. }
  44. wp->scoreboard = fpm_shm_alloc(sizeof(struct fpm_scoreboard_s) + (wp->config->pm_max_children - 1) * sizeof(struct fpm_scoreboard_proc_s *));
  45. if (!wp->scoreboard) {
  46. return -1;
  47. }
  48. wp->scoreboard->nprocs = wp->config->pm_max_children;
  49. for (i = 0; i < wp->scoreboard->nprocs; i++) {
  50. wp->scoreboard->procs[i] = fpm_shm_alloc(sizeof(struct fpm_scoreboard_proc_s));
  51. if (!wp->scoreboard->procs[i]) {
  52. return -1;
  53. }
  54. memset(wp->scoreboard->procs[i], 0, sizeof(struct fpm_scoreboard_proc_s));
  55. }
  56. wp->scoreboard->pm = wp->config->pm;
  57. wp->scoreboard->start_epoch = time(NULL);
  58. strlcpy(wp->scoreboard->pool, wp->config->name, sizeof(wp->scoreboard->pool));
  59. }
  60. return 0;
  61. }
  62. /* }}} */
  63. void fpm_scoreboard_update(int idle, int active, int lq, int lq_len, int requests, int max_children_reached, int action, struct fpm_scoreboard_s *scoreboard) /* {{{ */
  64. {
  65. if (!scoreboard) {
  66. scoreboard = fpm_scoreboard;
  67. }
  68. if (!scoreboard) {
  69. zlog(ZLOG_WARNING, "Unable to update scoreboard: the SHM has not been found");
  70. return;
  71. }
  72. fpm_spinlock(&scoreboard->lock, 0);
  73. if (action == FPM_SCOREBOARD_ACTION_SET) {
  74. if (idle >= 0) {
  75. scoreboard->idle = idle;
  76. }
  77. if (active >= 0) {
  78. scoreboard->active = active;
  79. }
  80. if (lq >= 0) {
  81. scoreboard->lq = lq;
  82. }
  83. if (lq_len >= 0) {
  84. scoreboard->lq_len = lq_len;
  85. }
  86. #ifdef HAVE_FPM_LQ /* prevent unnecessary test */
  87. if (scoreboard->lq > scoreboard->lq_max) {
  88. scoreboard->lq_max = scoreboard->lq;
  89. }
  90. #endif
  91. if (requests >= 0) {
  92. scoreboard->requests = requests;
  93. }
  94. if (max_children_reached >= 0) {
  95. scoreboard->max_children_reached = max_children_reached;
  96. }
  97. } else {
  98. if (scoreboard->idle + idle > 0) {
  99. scoreboard->idle += idle;
  100. } else {
  101. scoreboard->idle = 0;
  102. }
  103. if (scoreboard->active + active > 0) {
  104. scoreboard->active += active;
  105. } else {
  106. scoreboard->active = 0;
  107. }
  108. if (scoreboard->requests + requests > 0) {
  109. scoreboard->requests += requests;
  110. } else {
  111. scoreboard->requests = 0;
  112. }
  113. if (scoreboard->max_children_reached + max_children_reached > 0) {
  114. scoreboard->max_children_reached += max_children_reached;
  115. } else {
  116. scoreboard->max_children_reached = 0;
  117. }
  118. }
  119. if (scoreboard->active > scoreboard->active_max) {
  120. scoreboard->active_max = scoreboard->active;
  121. }
  122. fpm_unlock(scoreboard->lock);
  123. }
  124. /* }}} */
  125. struct fpm_scoreboard_s *fpm_scoreboard_get() /* {{{*/
  126. {
  127. return fpm_scoreboard;
  128. }
  129. /* }}} */
  130. struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get(struct fpm_scoreboard_s *scoreboard, int child_index) /* {{{*/
  131. {
  132. if (!scoreboard) {
  133. scoreboard = fpm_scoreboard;
  134. }
  135. if (!scoreboard) {
  136. return NULL;
  137. }
  138. if (child_index < 0) {
  139. child_index = fpm_scoreboard_i;
  140. }
  141. if (child_index < 0 || child_index >= scoreboard->nprocs) {
  142. return NULL;
  143. }
  144. return scoreboard->procs[child_index];
  145. }
  146. /* }}} */
  147. struct fpm_scoreboard_s *fpm_scoreboard_acquire(struct fpm_scoreboard_s *scoreboard, int nohang) /* {{{ */
  148. {
  149. struct fpm_scoreboard_s *s;
  150. s = scoreboard ? scoreboard : fpm_scoreboard;
  151. if (!s) {
  152. return NULL;
  153. }
  154. if (!fpm_spinlock(&s->lock, nohang)) {
  155. return NULL;
  156. }
  157. return s;
  158. }
  159. /* }}} */
  160. void fpm_scoreboard_release(struct fpm_scoreboard_s *scoreboard) {
  161. if (!scoreboard) {
  162. return;
  163. }
  164. scoreboard->lock = 0;
  165. }
  166. struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_acquire(struct fpm_scoreboard_s *scoreboard, int child_index, int nohang) /* {{{ */
  167. {
  168. struct fpm_scoreboard_proc_s *proc;
  169. proc = fpm_scoreboard_proc_get(scoreboard, child_index);
  170. if (!proc) {
  171. return NULL;
  172. }
  173. if (!fpm_spinlock(&proc->lock, nohang)) {
  174. return NULL;
  175. }
  176. return proc;
  177. }
  178. /* }}} */
  179. void fpm_scoreboard_proc_release(struct fpm_scoreboard_proc_s *proc) /* {{{ */
  180. {
  181. if (!proc) {
  182. return;
  183. }
  184. proc->lock = 0;
  185. }
  186. void fpm_scoreboard_free(struct fpm_scoreboard_s *scoreboard) /* {{{ */
  187. {
  188. int i;
  189. if (!scoreboard) {
  190. zlog(ZLOG_ERROR, "**scoreboard is NULL");
  191. return;
  192. }
  193. for (i = 0; i < scoreboard->nprocs; i++) {
  194. if (!scoreboard->procs[i]) {
  195. continue;
  196. }
  197. fpm_shm_free(scoreboard->procs[i], sizeof(struct fpm_scoreboard_proc_s));
  198. }
  199. fpm_shm_free(scoreboard, sizeof(struct fpm_scoreboard_s));
  200. }
  201. /* }}} */
  202. void fpm_scoreboard_child_use(struct fpm_scoreboard_s *scoreboard, int child_index, pid_t pid) /* {{{ */
  203. {
  204. struct fpm_scoreboard_proc_s *proc;
  205. fpm_scoreboard = scoreboard;
  206. fpm_scoreboard_i = child_index;
  207. proc = fpm_scoreboard_proc_get(scoreboard, child_index);
  208. if (!proc) {
  209. return;
  210. }
  211. proc->pid = pid;
  212. proc->start_epoch = time(NULL);
  213. }
  214. /* }}} */
  215. void fpm_scoreboard_proc_free(struct fpm_scoreboard_s *scoreboard, int child_index) /* {{{ */
  216. {
  217. if (!scoreboard) {
  218. return;
  219. }
  220. if (child_index < 0 || child_index >= scoreboard->nprocs) {
  221. return;
  222. }
  223. if (scoreboard->procs[child_index] && scoreboard->procs[child_index]->used > 0) {
  224. memset(scoreboard->procs[child_index], 0, sizeof(struct fpm_scoreboard_proc_s));
  225. }
  226. /* set this slot as free to avoid search on next alloc */
  227. scoreboard->free_proc = child_index;
  228. }
  229. /* }}} */
  230. int fpm_scoreboard_proc_alloc(struct fpm_scoreboard_s *scoreboard, int *child_index) /* {{{ */
  231. {
  232. int i = -1;
  233. if (!scoreboard || !child_index) {
  234. return -1;
  235. }
  236. /* first try the slot which is supposed to be free */
  237. if (scoreboard->free_proc >= 0 && scoreboard->free_proc < scoreboard->nprocs) {
  238. if (scoreboard->procs[scoreboard->free_proc] && !scoreboard->procs[scoreboard->free_proc]->used) {
  239. i = scoreboard->free_proc;
  240. }
  241. }
  242. if (i < 0) { /* the supposed free slot is not, let's search for a free slot */
  243. zlog(ZLOG_DEBUG, "[pool %s] the proc->free_slot was not free. Let's search", scoreboard->pool);
  244. for (i = 0; i < scoreboard->nprocs; i++) {
  245. if (scoreboard->procs[i] && !scoreboard->procs[i]->used) { /* found */
  246. break;
  247. }
  248. }
  249. }
  250. /* no free slot */
  251. if (i < 0 || i >= scoreboard->nprocs) {
  252. zlog(ZLOG_ERROR, "[pool %s] no free scoreboard slot", scoreboard->pool);
  253. return -1;
  254. }
  255. scoreboard->procs[i]->used = 1;
  256. *child_index = i;
  257. /* supposed next slot is free */
  258. if (i + 1 >= scoreboard->nprocs) {
  259. scoreboard->free_proc = 0;
  260. } else {
  261. scoreboard->free_proc = i + 1;
  262. }
  263. return 0;
  264. }
  265. /* }}} */
  266. #ifdef HAVE_TIMES
  267. float fpm_scoreboard_get_tick() /* {{{ */
  268. {
  269. return fpm_scoreboard_tick;
  270. }
  271. /* }}} */
  272. #endif