Beispiel #1
0
int main()
{
	int el, t;
	struct cfifo f;
	cfifo_init(&f, sizeof(int), 5);

	/* Initialization assertions */
	assert(f.cap == 5);
	assert(f.h == 0);
	assert(f.len == 0);
	assert(f.sz == sizeof(int));
	assert(f.ptr != 0);
	assert(cfifo_isempty(&f));
	assert(!cfifo_isfull(&f));

	/* After one push */
	el = 1, cfifo_push(&f, &el);
	assert(f.len == 1);
	assert(!cfifo_isempty(&f));
	assert(!cfifo_isfull(&f));

	/* After one pop */
	cfifo_pop(&f, &t);
	assert(el == t);
	assert(f.len == 0);
	assert(f.h == 1);
	assert(cfifo_isempty(&f));

	/* Push until full */
	el = 1, cfifo_push(&f, &el);
	el = 2, cfifo_push(&f, &el);
	el = 3, cfifo_push(&f, &el);
	el = 4, cfifo_push(&f, &el);
	el = 5, cfifo_push(&f, &el);
	assert(cfifo_isfull(&f));
	assert(!cfifo_isempty(&f));

	/* Push to overwrite head */
	el = 6, cfifo_push(&f, &el);
	assert(cfifo_isfull(&f));
	assert(!cfifo_isempty(&f));

	/* Pop until empty */
	cfifo_pop(&f, &el), assert(el == 2);
	cfifo_pop(&f, &el), assert(el == 3);
	cfifo_pop(&f, &el), assert(el == 4);
	cfifo_pop(&f, &el), assert(el == 5);
	cfifo_pop(&f, &el), assert(el == 6);
	assert(cfifo_isempty(&f));
	assert(!cfifo_isfull(&f));
	cfifo_free(&f);

	return 0;
}
Beispiel #2
0
// Function responsible for the workers on current TM node.
void *worker(void *ptr)
{
    int my_rank = COMM_get_rank_id(); 
    int task_id, j_id=0;                                        // j_id = journal id for current thread.
    struct tm_thread_data *d = (struct tm_thread_data *) ptr;
    struct byte_array * task;
    struct result_node * result;
    uint64_t buffer;
    struct j_entry * entry;

    workerid = d->id;

    void* (*worker_new) (int, char **);
    worker_new = dlsym(d->handle, "spits_worker_new");

    void (*execute_pit) (void *, struct byte_array *, struct byte_array *);
    execute_pit = dlsym(d->handle, "spits_worker_run");

    void* (*worker_free) (void *);
    worker_free = dlsym(d->handle, "spits_worker_free");

    void *user_data = worker_new ? worker_new(d->argc, d->argv) : NULL;

    if(TM_KEEP_JOURNAL > 0) {
        j_id = JOURNAL_get_id(d->dia, 'W');
    }

    sem_wait (&d->tcount);                                      // wait for the first task to arrive.
    while (d->running) {
        pthread_mutex_lock(&d->tlock);                          // Get a new task.
        cfifo_pop(&d->f, &task);
        pthread_mutex_unlock(&d->tlock);

        // Warn the Task Manager about the new space available.
        sem_post(&d->sem);

        byte_array_unpack64(task, &buffer);
        task_id = (int) buffer;
        debug("[worker] Received TASK %d", task_id);
        
        //_byte_array_pack64(task, (uint64_t) task_id);           // Put it back, might use in execute_pit.
        result = (struct result_node *) malloc(sizeof(struct result_node));
        byte_array_init(&result->ba, 10);
        byte_array_pack64(&result->ba, task_id);                // Pack the ID in the result byte_array.
        byte_array_pack64(&result->ba, my_rank);

        if(TM_KEEP_JOURNAL > 0) {
            entry = JOURNAL_new_entry(d->dia, j_id);
            entry->action = 'P';
            gettimeofday(&entry->start, NULL);
        }

        debug("[--WORKER] task: %d", task);
        debug("[--WORKER] &result->ba: %d", &result->ba);
        execute_pit(user_data, task, &result->ba);              // Do the computation.

        if(TM_KEEP_JOURNAL > 0) {
            gettimeofday(&entry->end, NULL);
        }

        byte_array_free(task);                                  // Free memory used in task and pointer.
        free(task);                                             // For now, each pointer is allocated in master thread.

        debug("Appending task %d.", task_id);
        pthread_mutex_lock(&d->rlock);                          // Pack the result to send it later.
        result->next = d->results; 
        result->before = NULL;
        result->task_id = task_id;
        if(d->results != NULL) {
            d->results->before = result;
        }
        d->results = result;
        
        if(d->is_blocking_flush==1) {
            if(TM_NO_WAIT_FINAL_FLUSH > 0) {
                sem_post(&d->no_wait_sem);
            }
            else {
                d->bf_remaining_tasks--;
                if(d->bf_remaining_tasks==0) {
                    pthread_mutex_unlock(&d->bf_mutex);
                }
            }
        }
            
        pthread_mutex_unlock(&d->rlock);

        sem_wait (&d->tcount);                                  // wait for the next task to arrive.
    }

    if (worker_free) {
        worker_free(user_data);
    }

    //free(result);
    pthread_exit(NULL);
}