root/sapi/fpm/fpm/fpm_scoreboard.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fpm_scoreboard_init_main
  2. fpm_scoreboard_update
  3. fpm_scoreboard_get
  4. fpm_scoreboard_proc_get
  5. fpm_scoreboard_acquire
  6. fpm_scoreboard_release
  7. fpm_scoreboard_proc_acquire
  8. fpm_scoreboard_proc_release
  9. fpm_scoreboard_free
  10. fpm_scoreboard_child_use
  11. fpm_scoreboard_proc_free
  12. fpm_scoreboard_proc_alloc
  13. fpm_scoreboard_get_tick

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

/* [<][>][^][v][top][bottom][index][help] */