コード例 #1
0
ファイル: test-cfifo.c プロジェクト: ianliu/cfifo
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;
}
コード例 #2
0
ファイル: taskmanager.c プロジェクト: albf/spitz
// Responsible for the thread that manages the Task Manager: receiving tasks,
// Sending results, requesting new tasks and etc.
void task_manager(struct tm_thread_data *d)
{
    int end = 0;                                                    // To indicate a true ending. Dead but fine. 
    enum message_type mtype;                                        // Type of received message.
    int min_results = TM_RESULT_BUFFER_SIZE;                        // Minimum of results to send at the same time. 
    enum blocking b = NONBLOCKING;                                  // Indicates if should block or not in flushing.
    int comm_return=0;                                              // Return values from send and read.
    int flushed_tasks;                                              // Return value from flush_results.
    int tm_retries;                                                 // Count the number of times TM tries to reconnect.
    int task_wait_max=1;                                            // Current max time of wait in CASE MSG_NO_TASK (sec)
    int wait;                                                       // wait(sec) in CASE MSG_NO_TASK
    int j_id=0;                                                     // Id from journal (if it exists).
    struct j_entry * entry;                                         // new entry for journal.

    // Data structure to exchange message between processes. 
    struct byte_array * ba;

    d->tasks = 0;                                                  // Tasks received and not committed.
    d->alive = 1;                                                  // Indicate if it still alive.
    srand (time(NULL));

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

    info("Starting task manager main loop");
    while (d->alive) {
        ba = (struct byte_array *) malloc(sizeof(struct byte_array));
        byte_array_init(ba, 100);

        debug("Sending READY message to JOB_MANAGER");

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

        comm_return = COMM_send_message(NULL, MSG_READY, socket_manager);
        if(comm_return < 0) {
            if(TM_KEEP_JOURNAL > 0) {
                gettimeofday(&entry->end, NULL);
            }


            if(COMM_get_actor_type() == VM_TASK_MANAGER) {
                error("Dumping VM journal");
                vm_dump_journal(d);
            }

            error("Problem found sending message to Job Manager");
            mtype = MSG_EMPTY;
        }
        else {
            comm_return = COMM_read_message(ba, &mtype, socket_manager);
            if(TM_KEEP_JOURNAL > 0) {
                gettimeofday(&entry->end, NULL);
                if(mtype == MSG_TASK) {
                    debug("Received MSG_TASK of size : %d", (int)ba->len);
                    entry->size = (int)ba->len;
                }
            }

            if(comm_return < 0) {
                error("Problem found to read message from Job Manager");
                mtype = MSG_EMPTY;

                if(COMM_get_actor_type() == VM_TASK_MANAGER) {
                    error("Dumping VM journal");
                    vm_dump_journal(d);
                }
            } 
        }

        switch (mtype) {
            case MSG_TASK:
                // Received at least one, mark to reuse id if connection problem occurs.
                if(received_one ==0 ) {
                    received_one = 1;
                }
                debug("waiting task buffer to free some space");
                sem_wait(&d->sem);

                pthread_mutex_lock(&d->tlock);
                cfifo_push(&d->f, &ba);
                pthread_mutex_unlock(&d->tlock);
                sem_post(&d->tcount);
                
                if(TM_FLUSHER_THREAD > 0) {
                    pthread_mutex_lock(&d->tasks_lock);
                    d->tasks++;
                    pthread_mutex_unlock(&d->tasks_lock);
                } 
                else {
                    d->tasks++;
                }

                break;
            case MSG_KILL:
                info("Got a KILL message");
                d->alive = 0;
                end = 1;
                b = BLOCKING;
                break;
            case MSG_EMPTY:
                COMM_close_connection(socket_manager);
                tm_retries = TM_CON_RETRIES;
                if(COMM_connect_to_job_manager(COMM_addr_manager, &tm_retries)!=0) {
                    info("Couldn't reconnect to the Job Manager. Closing Task Manager.");
                    d->alive = 0;
                }
                else {
                    info("Reconnected to the Job Manager.");
                }
                break;
            case MSG_NO_TASK:
                wait = int_rand(1, task_wait_max);
                debug("No task available, is it still loading? Sleeping for %d seconds", wait);
                sleep(wait);
                task_wait_max = task_wait_max * 2;
                if(task_wait_max > TM_MAX_SLEEP) {
                    task_wait_max = TM_MAX_SLEEP;
                }
                break;
            default:
                break;
        }

        if (d->alive || end) {
            debug("Trying to flush %d %s...", min_results, b == BLOCKING ? "blocking":"non blocking");
            if(TM_FLUSHER_THREAD > 0) {
                if((d->tasks >= min_results) || (b == BLOCKING)) {
                    pthread_mutex_lock(&d->flusher_d_mutex);
                    d->flusher_min_results = min_results;
                    d->flusher_b = b;
                    sem_post(&d->flusher_r_sem);
                }
            }
            else {
                if(b == BLOCKING) {
                    min_results = d->tasks;
                }

                flushed_tasks = 0;
                if(d->tasks >= min_results) {
                    flushed_tasks = flush_results(d, min_results, b, j_id);
                }

                if(flushed_tasks < 0) {
                    info("Couldn't flush results. Is committer still alive?");
                    tm_retries = TM_CON_RETRIES;
                    if(COMM_connect_to_committer(&tm_retries)<0) {
                        info("If it is, I just couldn't find it. Closing.");
                        d->alive = 0;
                    }
                    else {
                        info("Reconnected to the committer.");
                    }
                }
                else {
                    d->tasks = d->tasks - flushed_tasks; 
                    debug("I have sent %d tasks\n", flushed_tasks);
                }
            }
        }
    }

    info("Terminating task manager");
    byte_array_free(ba);
    free(ba);
}