Esempio n. 1
0
/*===========================================================================*
 *				get_work				     *
 *===========================================================================*/
static void get_work(struct worker_thread *worker)
{
/* Find new work to do. Work can be 'queued', 'pending', or absent. In the
 * latter case wait for new work to come in. */

  struct job *new_job;
  struct fproc *rfp;

  ASSERTW(worker);
  self = worker;

  /* Do we have queued work to do? */
  if ((new_job = worker->w_job.j_next) != NULL) {
	worker->w_job = *new_job;
	free(new_job);
	return;
  } else if (worker != &sys_worker && worker != &dl_worker && pending > 0) {
	/* Find pending work */
	for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
		if (rfp->fp_flags & FP_PENDING) {
			worker->w_job = rfp->fp_job;
			rfp->fp_job.j_func = NULL;
			rfp->fp_flags &= ~FP_PENDING; /* No longer pending */
			pending--;
			assert(pending >= 0);
			return;
		}
	}
	panic("Pending work inconsistency");
  }

  /* Wait for work to come to us */
  worker_sleep(worker);
}
Esempio n. 2
0
/**
 * Work.
 *
 */
void
worker_start(worker_type* worker)
{
    time_t now, timeout = 1;
    task_type *task_that_was_worked_on;

    ods_log_assert(worker);

    while (worker->need_to_exit == 0) {
        ods_log_debug("[worker[%i]]: report for duty", worker->thread_num);

        lock_basic_lock(&worker->engine->taskq->schedule_lock);
        /* [LOCK] schedule */

        worker->task = schedule_pop_task(worker->engine->taskq);
        if (worker->task) {

            /* [UNLOCK] schedule */
            lock_basic_unlock(&worker->engine->taskq->schedule_lock);

            ods_log_debug("[worker[%i]] start working", worker->thread_num);

            worker->clock_in = time(NULL);
            worker_perform_task(worker);

            task_that_was_worked_on = worker->task;
            worker->task = NULL;
            
            ods_log_debug("[worker[%i]] finished working", worker->thread_num);
            
            if (task_that_was_worked_on)
                (void) lock_and_schedule_task(worker->engine->taskq,
                                                 task_that_was_worked_on, 1);
            
            timeout = 1;
        } else {
            ods_log_debug("[worker[%i]] nothing to do", worker->thread_num);

            worker->task = schedule_get_first_task(worker->engine->taskq);

            /* [UNLOCK] schedule */
            lock_basic_unlock(&worker->engine->taskq->schedule_lock);

            now = time_now();
            if (worker->task && !worker->engine->taskq->loading) {
                timeout = (worker->task->when - now);
            } else {
                timeout *= 2;
                if (timeout > ODS_SE_MAX_BACKOFF) {
                    timeout = ODS_SE_MAX_BACKOFF;
                }
            }
            worker->task = NULL;
            worker_sleep(worker, timeout);
        }
    }
    return;
}
Esempio n. 3
0
/*===========================================================================*
 *				worker_wait				     *
 *===========================================================================*/
void worker_wait(void)
{
  self->w_job.j_err_code = err_code;
  worker_sleep(self);
  /* We continue here after waking up */
  fp = self->w_job.j_fp;	/* Restore global data */
  err_code = self->w_job.j_err_code;
  assert(self->w_next == NULL);
}
/**
 * Work.
 *
 */
static void
worker_work(worker_type* worker)
{
    time_t now = 0;
    time_t timeout = 1;
    engine_type* engine = NULL;
    zone_type* zone = NULL;
    ods_status status = ODS_STATUS_OK;

    ods_log_assert(worker);
    ods_log_assert(worker->type == WORKER_WORKER);

    engine = (engine_type*) worker->engine;
    while (worker->need_to_exit == 0) {
        ods_log_debug("[%s[%i]] report for duty", worker2str(worker->type),
            worker->thread_num);
        now = time_now();
        lock_basic_lock(&engine->taskq->schedule_lock);
        worker->task = schedule_pop_task(engine->taskq);
        if (worker->task) {
            worker->working_with = worker->task->what;
            lock_basic_unlock(&engine->taskq->schedule_lock);
            zone = (zone_type*) worker->task->zone;

            lock_basic_lock(&zone->zone_lock);
            ods_log_debug("[%s[%i]] start working on zone %s",
                worker2str(worker->type), worker->thread_num, zone->name);
            worker->clock_in = time(NULL);
            worker_perform_task(worker);
            zone->task = worker->task;
            ods_log_debug("[%s[%i]] finished working on zone %s",
                worker2str(worker->type), worker->thread_num, zone->name);

            lock_basic_lock(&engine->taskq->schedule_lock);
            worker->task = NULL;
            worker->working_with = TASK_NONE;
            status = schedule_task(engine->taskq, zone->task, 1);
            if (status != ODS_STATUS_OK) {
                ods_log_error("[%s[%i]] unable to schedule task for zone %s: "
                "%s", worker2str(worker->type), worker->thread_num,
                zone->name, ods_status2str(status));
            }
            lock_basic_unlock(&engine->taskq->schedule_lock);
            lock_basic_unlock(&zone->zone_lock);
            timeout = 1;
            /** Do we need to tell the engine that we require a reload? */
            lock_basic_lock(&engine->signal_lock);
            if (engine->need_to_reload) {
                lock_basic_alarm(&engine->signal_cond);
            }
            lock_basic_unlock(&engine->signal_lock);

        } else {
            ods_log_debug("[%s[%i]] nothing to do", worker2str(worker->type),
                worker->thread_num);
            worker->task = schedule_get_first_task(engine->taskq);
            lock_basic_unlock(&engine->taskq->schedule_lock);
            if (worker->task && !engine->taskq->loading) {
                timeout = (worker->task->when - now);
            } else {
                timeout *= 2;
            }
            if (timeout > ODS_SE_MAX_BACKOFF) {
                timeout = ODS_SE_MAX_BACKOFF;
            }
            worker->task = NULL;
            worker_sleep(worker, timeout);
        }
    }
    return;
}