Browse Source

Rework the user and worker examining loops in statsupdate to not hold the instance lock

master
Con Kolivas 8 years ago
parent
commit
ead718a5b5
  1. 44
      src/stratifier.c

44
src/stratifier.c

@ -7108,6 +7108,35 @@ static void upstream_workers(ckpool_t *ckp, user_instance_t *user)
send_proc(ckp->connector, buf);
}
/* To iterate over all users, if user is initially NULL, this will return the first entry,
* otherwise it will return the entry after user, and NULL if there are no more entries.
* Allows us to grab and drop the lock on each iteration. */
static user_instance_t *next_user(sdata_t *sdata, user_instance_t *user)
{
ck_rlock(&sdata->instance_lock);
if (unlikely(!user))
user = sdata->user_instances;
else
user = user->hh.next;
ck_runlock(&sdata->instance_lock);
return user;
}
/* Ditto for worker */
static worker_instance_t *next_worker(sdata_t *sdata, user_instance_t *user, worker_instance_t *worker)
{
ck_rlock(&sdata->instance_lock);
if (!worker)
worker = user->worker_instances;
else
worker = worker->next;
ck_runlock(&sdata->instance_lock);
return worker;
}
static void *statsupdate(void *arg)
{
ckpool_t *ckp = (ckpool_t *)arg;
@ -7126,9 +7155,9 @@ static void *statsupdate(void *arg)
char suffix1[16], suffix5[16], suffix15[16], suffix60[16], cdfield[64];
char suffix360[16], suffix1440[16], suffix10080[16];
log_entry_t *log_entries = NULL;
user_instance_t *user, *tmpuser;
char_entry_t *char_list = NULL;
stratum_instance_t *client;
user_instance_t *user;
int idle_workers = 0;
char *fname, *s, *sp;
tv_t now, diff;
@ -7148,6 +7177,7 @@ static void *statsupdate(void *arg)
ck_wunlock(&sdata->instance_lock);
while (client) {
tv_time(&now);
/* Look for clients that may have been dropped which the
* stratifier has not been informed about and ask the
* connector if they still exist */
@ -7188,17 +7218,20 @@ static void *statsupdate(void *arg)
ck_wunlock(&sdata->instance_lock);
}
/* Drop and regain lock to minimise lock hold time */
ck_rlock(&sdata->instance_lock);
HASH_ITER(hh, sdata->user_instances, user, tmpuser) {
user = NULL;
while ((user = next_user(sdata, user)) != NULL) {
worker_instance_t *worker;
bool idle = false;
if (!user->authorised)
continue;
worker = NULL;
tv_time(&now);
/* Decay times per worker */
DL_FOREACH(user->worker_instances, worker) {
while ((worker = next_worker(sdata, user, worker)) != NULL) {
per_tdiff = tvdiff(&now, &worker->last_share);
if (per_tdiff > 60) {
decay_worker(worker, 0, &now);
@ -7287,7 +7320,6 @@ static void *statsupdate(void *arg)
if (ckp->remote)
upstream_workers(ckp, user);
}
ck_runlock(&sdata->instance_lock);
/* Dump log entries out of instance_lock */
dump_log_entries(&log_entries);

Loading…
Cancel
Save