18static int fpm_scoreboard_i = -1;
20static float fpm_scoreboard_tick;
30 fpm_scoreboard_tick = sysconf(_SC_CLK_TCK);
33 fpm_scoreboard_tick = HZ;
35 fpm_scoreboard_tick = 100;
43 size_t scoreboard_procs_size;
76static inline void fpm_scoreboard_readers_decrement(
struct fpm_scoreboard_s *scoreboard)
78 fpm_spinlock(&scoreboard->
lock, 1);
82#ifdef PHP_FPM_ZLOG_TRACE
83 unsigned int current_reader_count = scoreboard->
reader_count;
86#ifdef PHP_FPM_ZLOG_TRACE
88 zlog(
ZLOG_DEBUG,
"scoreboard: for proc %d reader decremented to value %u", getpid(), current_reader_count);
95 scoreboard = fpm_scoreboard;
98 zlog(
ZLOG_WARNING,
"Unable to update scoreboard: the SHM has not been found");
107 scoreboard = fpm_scoreboard_get_for_update(scoreboard);
114 fpm_spinlock(&scoreboard->
lock, 1);
118 zlog(
ZLOG_WARNING,
"scoreboard: writer %d waited too long for another writer to release lock.", getpid());
120#ifdef PHP_FPM_ZLOG_TRACE
122 zlog(
ZLOG_DEBUG,
"scoreboard: writer lock acquired by writer %d", getpid());
132 fpm_scoreboard_readers_decrement(scoreboard);
133 zlog(
ZLOG_WARNING,
"scoreboard: writer detected a potential crashed reader, decrementing reader count.");
146 scoreboard = fpm_scoreboard_get_for_update(scoreboard);
165 if (scoreboard->
lq > scoreboard->
lq_max) {
166 scoreboard->
lq_max = scoreboard->
lq;
183 scoreboard->
idle = 0;
219#ifdef PHP_FPM_ZLOG_TRACE
220 zlog(
ZLOG_DEBUG,
"scoreboard: writer lock released by writer %d", getpid());
238 return fpm_scoreboard;
248 if (child_index < 0 || (
unsigned int)child_index >= nprocs) {
252 return &scoreboard->procs[child_index];
260 scoreboard = fpm_scoreboard;
263 if (child_index < 0) {
264 child_index = fpm_scoreboard_i;
267 return fpm_scoreboard_proc_get_ex(scoreboard, child_index, scoreboard->
nprocs);
278 return fpm_scoreboard_proc_get_ex(scoreboard, child_index,
nprocs);
293 fpm_spinlock(&
s->lock, 1);
294 if (!
s->writer_active) {
295 s->reader_count += 1;
296#ifdef PHP_FPM_ZLOG_TRACE
297 unsigned int current_reader_count =
s->reader_count;
300#ifdef PHP_FPM_ZLOG_TRACE
301 zlog(
ZLOG_DEBUG,
"scoreboard: for proc %d reader incremented to value %u", getpid(), current_reader_count);
310 zlog(
ZLOG_WARNING,
"scoreboard: reader waited too long for writer to release lock.");
311 fpm_scoreboard_readers_decrement(
s);
325 fpm_scoreboard_readers_decrement(scoreboard);
332 size_t scoreboard_size, scoreboard_nprocs_size;
344 mem = malloc(scoreboard_size + scoreboard_nprocs_size);
350 zlog(
ZLOG_ERROR,
"scoreboard: failed to allocate memory for copy");
354 scoreboard_copy = mem;
363 *scoreboard_copy = *scoreboard;
366 mem += scoreboard_size;
370 scoreboard_copy->procs[i] = *scoreboard_proc_p;
377 return scoreboard_copy;
394 if (!fpm_spinlock(&proc->
lock, nohang)) {
413 size_t scoreboard_procs_size;
455 if (scoreboard->procs[child_index].used > 0) {
477 if (!scoreboard->procs[scoreboard->
free_proc].used) {
483 zlog(
ZLOG_DEBUG,
"[pool %s] the proc->free_slot was not free. Let's search", scoreboard->
pool);
484 for (i = 0; i <
nprocs; i++) {
485 if (!scoreboard->procs[i].used) {
492 if (i < 0 || i >=
nprocs) {
497 scoreboard->procs[i].used = 1;
512float fpm_scoreboard_get_tick(
void)
514 return fpm_scoreboard_tick;
memset(ptr, 0, type->size)
struct fpm_scoreboard_proc_s * fpm_scoreboard_proc_acquire(struct fpm_scoreboard_s *scoreboard, int child_index, int nohang)
void fpm_scoreboard_free(struct fpm_worker_pool_s *wp)
void fpm_scoreboard_free_copy(struct fpm_scoreboard_s *scoreboard)
int fpm_scoreboard_init_main(void)
void fpm_scoreboard_release(struct fpm_scoreboard_s *scoreboard)
struct fpm_scoreboard_proc_s * fpm_scoreboard_proc_get_from_child(struct fpm_child_s *child)
void fpm_scoreboard_update_begin(struct fpm_scoreboard_s *scoreboard)
void fpm_scoreboard_proc_release(struct fpm_scoreboard_proc_s *proc)
void fpm_scoreboard_child_use(struct fpm_child_s *child, pid_t pid)
void fpm_scoreboard_update_commit(int idle, int active, int lq, int lq_len, int requests, int max_children_reached, int slow_rq, size_t memory_peak, int action, struct fpm_scoreboard_s *scoreboard)
struct fpm_scoreboard_s * fpm_scoreboard_get(void)
struct fpm_scoreboard_proc_s * fpm_scoreboard_proc_get(struct fpm_scoreboard_s *scoreboard, int child_index)
struct fpm_scoreboard_s * fpm_scoreboard_copy(struct fpm_scoreboard_s *scoreboard, int copy_procs)
void fpm_scoreboard_proc_free(struct fpm_child_s *child)
int fpm_scoreboard_proc_alloc(struct fpm_child_s *child)
void fpm_scoreboard_update(int idle, int active, int lq, int lq_len, int requests, int max_children_reached, int slow_rq, size_t memory_peak, int action, struct fpm_scoreboard_s *scoreboard)
struct fpm_scoreboard_s * fpm_scoreboard_acquire(struct fpm_scoreboard_s *scoreboard, int nohang)
#define FPM_SCOREBOARD_LOCK_NOHANG
#define FPM_SCOREBOARD_ACTION_SET
struct fpm_scoreboard_proc_s * fpm_scoreboard_proc_acquire(struct fpm_scoreboard_s *scoreboard, int child_index, int nohang)
#define FPM_SCOREBOARD_SPINLOCK_MAX_RETRIES
void fpm_scoreboard_proc_release(struct fpm_scoreboard_proc_s *proc)
#define FPM_SCOREBOARD_LOCK_HANG
int fpm_shm_free(void *mem, size_t size)
void * fpm_shm_alloc(size_t size)
struct fpm_worker_pool_s * fpm_worker_all_pools
php_output_handler * active
struct fpm_worker_pool_s * wp
unsigned int max_children_reached
unsigned int reader_count
struct fpm_scoreboard_s * shared
unsigned long int slow_rq
unsigned long int requests
struct fpm_worker_pool_config_s * config
struct fpm_worker_pool_s * shared
struct fpm_scoreboard_s * scoreboard
struct fpm_worker_pool_s * next