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); 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) static void *statsupdate(void *arg)
{ {
ckpool_t *ckp = (ckpool_t *)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 suffix1[16], suffix5[16], suffix15[16], suffix60[16], cdfield[64];
char suffix360[16], suffix1440[16], suffix10080[16]; char suffix360[16], suffix1440[16], suffix10080[16];
log_entry_t *log_entries = NULL; log_entry_t *log_entries = NULL;
user_instance_t *user, *tmpuser;
char_entry_t *char_list = NULL; char_entry_t *char_list = NULL;
stratum_instance_t *client; stratum_instance_t *client;
user_instance_t *user;
int idle_workers = 0; int idle_workers = 0;
char *fname, *s, *sp; char *fname, *s, *sp;
tv_t now, diff; tv_t now, diff;
@ -7148,6 +7177,7 @@ static void *statsupdate(void *arg)
ck_wunlock(&sdata->instance_lock); ck_wunlock(&sdata->instance_lock);
while (client) { while (client) {
tv_time(&now);
/* Look for clients that may have been dropped which the /* Look for clients that may have been dropped which the
* stratifier has not been informed about and ask the * stratifier has not been informed about and ask the
* connector if they still exist */ * connector if they still exist */
@ -7188,17 +7218,20 @@ static void *statsupdate(void *arg)
ck_wunlock(&sdata->instance_lock); ck_wunlock(&sdata->instance_lock);
} }
/* Drop and regain lock to minimise lock hold time */ user = NULL;
ck_rlock(&sdata->instance_lock);
HASH_ITER(hh, sdata->user_instances, user, tmpuser) { while ((user = next_user(sdata, user)) != NULL) {
worker_instance_t *worker; worker_instance_t *worker;
bool idle = false; bool idle = false;
if (!user->authorised) if (!user->authorised)
continue; continue;
worker = NULL;
tv_time(&now);
/* Decay times per worker */ /* 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); per_tdiff = tvdiff(&now, &worker->last_share);
if (per_tdiff > 60) { if (per_tdiff > 60) {
decay_worker(worker, 0, &now); decay_worker(worker, 0, &now);
@ -7287,7 +7320,6 @@ static void *statsupdate(void *arg)
if (ckp->remote) if (ckp->remote)
upstream_workers(ckp, user); upstream_workers(ckp, user);
} }
ck_runlock(&sdata->instance_lock);
/* Dump log entries out of instance_lock */ /* Dump log entries out of instance_lock */
dump_log_entries(&log_entries); dump_log_entries(&log_entries);

Loading…
Cancel
Save