Beispiel #1
0
/* Get first job from queue(removes it from queue)
 *
 * Notice: Caller MUST hold a mutex
 */
static struct job* jobqueue_pull(thpool_* thpool_p){

	job* job_p;
	job_p = thpool_p->jobqueue_p->front;

	switch(thpool_p->jobqueue_p->len){

		case 0:  /* if no jobs in queue */
		  			break;

		case 1:  /* if one job in queue */
					thpool_p->jobqueue_p->front = NULL;
					thpool_p->jobqueue_p->rear  = NULL;
					thpool_p->jobqueue_p->len = 0;
					break;

		default: /* if >1 jobs in queue */
					thpool_p->jobqueue_p->front = job_p->prev;
					thpool_p->jobqueue_p->len--;
					/* more than one job in queue -> post it */
					bsem_post(thpool_p->jobqueue_p->has_jobs);

	}

	return job_p;
}
Beispiel #2
0
/* Get first job from queue(removes it from queue)
 * 
 * Notice: Caller MUST hold a mutex
 */
static struct job* jobqueue_pull(thpool_* thpool_p){

	job* job_p;
	job_p = thpool_p->jobqueue_p->front;

	switch(thpool_p->jobqueue_p->len){
		
		case 0:  /* if no jobs in queue */
					return NULL;
		
		case 1:  /* if one job in queue */
					thpool_p->jobqueue_p->front = NULL;
					thpool_p->jobqueue_p->rear  = NULL;
					break;
		
		default: /* if >1 jobs in queue */
					thpool_p->jobqueue_p->front = job_p->prev;
					
	}
	thpool_p->jobqueue_p->len--;
	
	/* Make sure has_jobs has right value */
	if (thpool_p->jobqueue_p->len > 0) {
		bsem_post(thpool_p->jobqueue_p->has_jobs);
	}

	return job_p;
}
Beispiel #3
0
/**
 * Add (allocated) job to queue
 */
static void jobqueue_push(JobQueue* queue,
                          Job* newjob) {
    pthread_mutex_lock(&queue->rwmutex);

    jobqueue_push_internal(queue, newjob);

    bsem_post(queue->has_jobs);

    pthread_mutex_unlock(&queue->rwmutex);
}
Beispiel #4
0
/* Add (allocated) job to queue
 *
 * Notice: Caller MUST hold a mutex
 */
static void jobqueue_push(thpool_* thpool_p, struct job* newjob){

	newjob->prev = NULL;

	switch(thpool_p->jobqueue_p->len){

		case 0:  /* if no jobs in queue */
					thpool_p->jobqueue_p->front = newjob;
					thpool_p->jobqueue_p->rear  = newjob;
					break;

		default: /* if jobs in queue */
					thpool_p->jobqueue_p->rear->prev = newjob;
					thpool_p->jobqueue_p->rear = newjob;
					
	}
	thpool_p->jobqueue_p->len++;
	
	bsem_post(thpool_p->jobqueue_p->has_jobs);
}
Beispiel #5
0
/* Add (allocated) job to queue
 */
static void jobqueue_push(jobqueue* jobqueue_p, struct job* newjob){

	pthread_mutex_lock(&jobqueue_p->rwmutex);
	newjob->prev = NULL;

	switch(jobqueue_p->len){

		case 0:  /* if no jobs in queue */
					jobqueue_p->front = newjob;
					jobqueue_p->rear  = newjob;
					break;

		default: /* if jobs in queue */
					jobqueue_p->rear->prev = newjob;
					jobqueue_p->rear = newjob;
					
	}
	jobqueue_p->len++;
	
	bsem_post(jobqueue_p->has_jobs);
	pthread_mutex_unlock(&jobqueue_p->rwmutex);
}
Beispiel #6
0
/**
 * Get jobs from the queue(removes them from the queue)
 *
 * Notice: Caller MUST hold a mutex
 */
static WorkGroup* jobqueue_pull(ThPool* thpool,
                                int id) {

    WorkGroup* group;
    Job* job;
    float current_time;
    float duration, duration_next, min_duration, target_duration;
    struct timespec timeAux;
    int info;
    int i;
    JobQueue* queue = thpool->jobqueue;

    if (schedule_strategy == SCHED_STATIC && queue->group_front != NULL) {
        // STATIC
        group = queue->group_front;

        queue->group_front = group->prev;
        group->prev = NULL;

    } else if (queue->len == 0) {
        // nothing to do
        group = NULL;

    } else if (schedule_strategy == SCHED_DYNAMIC || queue->len == 1 || queue->total_time <= 0) {
        // SCHED_DYNAMIC
        group = (WorkGroup*) malloc(sizeof(WorkGroup));
        group->prev = NULL;

        if (cppadcg_pool_verbose) {
            if (schedule_strategy == SCHED_GUIDED) {
                if (queue->len == 1)
                    fprintf(stdout, "jobqueue_pull(): Thread %i given a work group with 1 job\n", id);
                else if (queue->total_time <= 0)
                    fprintf(stdout, "jobqueue_pull(): Thread %i using single-job instead of multi-job (no timing information)\n", id);
            } else if (schedule_strategy == SCHED_STATIC && queue->len >= 1) {
                if (queue->total_time >= 0) {
                    // this should not happen but just in case the user messed up
                    fprintf(stderr, "jobqueue_pull(): Thread %i given a work group with 1 job\n", id);
                } else {
                    fprintf(stdout, "jobqueue_pull(): Thread %i given a work group with 1 job\n", id);
                }
            }
        }

        jobqueue_extract_single_group(thpool->jobqueue, group);
    } else { // schedule_strategy == SCHED_GUIDED
        // SCHED_GUIDED
        group = (WorkGroup*) malloc(sizeof(WorkGroup));
        group->prev = NULL;

        job = queue->front;

        if (job->avgElapsed == NULL) {
            if (cppadcg_pool_verbose) {
                fprintf(stderr, "jobqueue_pull(): Thread %i using single job instead of multi-job (No timing information for current job)\n", id);
            }
            // cannot use this strategy (something went wrong!)
            jobqueue_extract_single_group(thpool->jobqueue, group);

        } else {
            // there are at least 2 jobs in the queue
            group->size = 1;
            duration = *job->avgElapsed;
            duration_next = duration;
            job = job->prev;
            target_duration = queue->total_time * cppadcg_pool_guided_maxgroupwork / thpool->num_threads; // always positive
            current_time = get_monotonic_time(&timeAux, &info);

            if (queue->highest_expected_return > 0 && info) {
                min_duration = 0.9f * (queue->highest_expected_return - current_time);
                if (target_duration < min_duration) {
                    target_duration = min_duration;
                }
            }

            do {
                if (job->avgElapsed == NULL) {
                    break;
                }
                duration_next += *job->avgElapsed;
                if (duration_next < target_duration) {
                    group->size++;
                    duration = duration_next;
                } else {
                    break;
                }
                job = job->prev;
            } while (job != queue->front);

            if (cppadcg_pool_verbose) {
                fprintf(stdout, "jobqueue_pull(): Thread %i given a work group with %i jobs for %e s (target: %e s)\n", id, group->size, duration, target_duration);
            }

            group->jobs = (Job*) malloc(group->size * sizeof(Job));
            for (i = 0; i < group->size; ++i) {
                job = jobqueue_extract_single(thpool->jobqueue);
                group->jobs[i] = *job; // copy
                free(job);
            }

            duration_next = current_time + duration; // the time when the current work is expected to end
            if(duration_next > queue->highest_expected_return)
                queue->highest_expected_return = duration_next;
        }

    }
    /* more than one job in queue -> post it */
    if (queue->len > 0 || queue->group_front != NULL) {
        bsem_post(queue->has_jobs);
    }

    return group;
}