void ptask_wait_for_period() { #ifdef TRACEPOINT_DEFINE if(_tp[ptask_idx].act_flag == NOW) tpoint("NOW", "b_wait_period"); else if(_tp[ptask_idx].act_flag == DEFERRED) tpoint("DEFERRED", "b_wait_period"); #endif pthread_mutex_lock(&_tp[ptask_idx].mux); if (_tp[ptask_idx].measure_flag) tstat_record(ptask_idx); if (_tp[ptask_idx].modes != NULL && !rtmode_taskfind(_tp[ptask_idx].modes, ptask_idx)) { maxsem_post(&_tp[ptask_idx].modes->manager, &_tp[ptask_idx].at); pthread_mutex_unlock(&_tp[ptask_idx].mux); ptask_wait_for_activation(); #ifdef TRACEPOINT_DEFINE if(_tp[ptask_idx].act_flag == NOW) tpoint("NOW", "e_wait_period"); else if(_tp[ptask_idx].act_flag == DEFERRED) tpoint("DEFERRED", "e_wait_period"); #endif return; } else { _tp[ptask_idx].state = TASK_WFP; pthread_mutex_unlock(&_tp[ptask_idx].mux); clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &(_tp[ptask_idx].at), NULL); pthread_mutex_lock(&_tp[ptask_idx].mux); _tp[ptask_idx].state = TASK_ACTIVE; /* update absolute deadline */ _tp[ptask_idx].dl = tspec_add(&(_tp[ptask_idx].at), &_tp[ptask_idx].deadline); /* when awaken, update next activation time */ _tp[ptask_idx].at = tspec_add(&(_tp[ptask_idx].at), &_tp[ptask_idx].period); pthread_mutex_unlock(&_tp[ptask_idx].mux); #ifdef TRACEPOINT_DEFINE if(_tp[ptask_idx].act_flag == NOW) tpoint("NOW", "e_wait_period"); else if(_tp[ptask_idx].act_flag == DEFERRED) tpoint("DEFERRED", "e_wait_period"); #endif return; } }
tspec pbarrier_wait(pbarrier_t *pb, tspec *offset) { pthread_mutex_lock(&pb->m); ++(pb->arrived); if (pb->arrived < pb->nthreads) pthread_cond_wait(&pb->c, &pb->m); else { clock_gettime(CLOCK_MONOTONIC, &pb->reference); pthread_cond_broadcast(&pb->c); pb->arrived = 0; printf("Last arrived\n"); fflush(stdout); } pthread_mutex_unlock(&pb->m); if (offset == 0) return pb->reference; else { tspec wake_up; wake_up = tspec_add(&pb->reference, offset); clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &wake_up, 0); return wake_up; } }
/* the thread body. 1) It does some book keeping and installs the exit handler. 2) if necessary, waits for the first activation 3) then calls the real user task body 4) on exit, it cleans up everything */ static void *ptask_std_body(void *arg) { struct task_par *pdes = (struct task_par *)arg; tspec t; ptask_idx = pdes->index; if (_tp[ptask_idx].measure_flag) tstat_init(ptask_idx); pthread_cleanup_push(ptask_exit_handler, 0); _tp[ptask_idx].tid = gettid(); if (ptask_policy == SCHED_DEADLINE) { struct sched_attr attr; attr.size = sizeof(attr); attr.sched_policy = SCHED_DEADLINE; attr.sched_flags = SCHED_FLAG_RESET_ON_FORK; attr.sched_priority = 0; attr.sched_runtime = (__u64)tspec_to(&(_tp[ptask_idx].runtime), NANO); attr.sched_period = (__u64)tspec_to(&_tp[ptask_idx].period, NANO); attr.sched_deadline = (__u64)tspec_to(&_tp[ptask_idx].deadline, NANO); if (sched_setattr(_tp[ptask_idx].tid, &attr, 0) != 0) { printf("ERROR in setting sched_deadline parameters!\n"); perror("Error:"); return 0; } _tp[ptask_idx].schedattr = attr; // printf("SCHED_DEADLINE correctly set\n"); } if (_tp[ptask_idx].act_flag == DEFERRED) ptask_wait_for_activation(); else { clock_gettime(CLOCK_MONOTONIC, &t); _tp[ptask_idx].dl = tspec_add(&t, &_tp[ptask_idx].deadline); _tp[ptask_idx].at = tspec_add(&t, &_tp[ptask_idx].period); } //dle_init(); /*< init dle handler for this task */ (*pdes->body)(); //dle_exit(); /*< cleanup dle handler for this task */ pthread_cleanup_pop(1); return 0; }
int ptask_activate(int i) { struct timespec t; int ret = 1; pthread_mutex_lock(&_tp[i].mux); if (_tp[i].state == TASK_ACTIVE || _tp[i].state == TASK_WFP) { ret = -1; } else { clock_gettime(CLOCK_MONOTONIC, &t); /* compute the absolute deadline */ _tp[i].dl = tspec_add(&t, &_tp[i].deadline); /* compute the next activation time */ _tp[i].at = tspec_add(&t, &_tp[i].period); /* send the activation signal */ sem_post(&_tsem[i]); } pthread_mutex_unlock(&_tp[i].mux); return ret; }
int ptask_activate_at(int i, ptime offset, int unit) { tspec reloff = tspec_from(offset, unit); tspec t; int ret = 1; pthread_mutex_lock(&_tp[i].mux); /* if (_tp[i].state == TASK_ACTIVE || _tp[i].state == TASK_WFP) { */ if (_tp[i].state == TASK_WFP) { ret = -1; } else { t = tspec_get_ref(); /* compute the absolute deadline */ _tp[i].offset = tspec_add(&t, &reloff); _tp[i].dl = tspec_add(&_tp[i].offset, &_tp[i].deadline); /* compute the next activation time */ _tp[i].at = tspec_add(&_tp[i].offset, &_tp[i].period); /* send the activation signal */ sem_post(&_tsem[i]); // printf("sem_post done on task %d\n", i); } pthread_mutex_unlock(&_tp[i].mux); return ret; }