예제 #1
0
파일: ptask.c 프로젝트: glipari/ptask
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;
    }
}
예제 #2
0
파일: pbarrier.c 프로젝트: balsini/ptask
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;
    }
}
예제 #3
0
파일: ptask.c 프로젝트: glipari/ptask
/* 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;
}
예제 #4
0
파일: ptask.c 프로젝트: glipari/ptask
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;
}
예제 #5
0
파일: ptask.c 프로젝트: glipari/ptask
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;
}