Beispiel #1
0
//-----------------------------------------------------------------------------------------------------
//Function called by worker thread. Processes items in IN_QUEUE by retrieving them, executing them,
// then adding them to OUT_QUEUE.
//-----------------------------------------------------------------------------------------------------
void* process_rules(void* arg)
{
	rule_t* cur_rule;

	while(1)
	{
		//If something gets stuck in dep_q this could be a problem, but helper thread should
		// exit if something is stuck
		
		//Only allow as many threads into in_q as items in the in_q
		sem_wait(&jobs_sem);

		//Check exit condition
		if(adding_Rules == 0 && in_q->index == 0 && dep_q->index == 0) break;

		//Get rule, execute, and put in out_q
		if((cur_rule = get_rule(IN_QUEUE, NULL)) == NULL) { fprintf(stderr, "Error, tried to access NULL queue\n"); continue; }
		//printf("EXECUTE(%u): %s\n", (unsigned int)pthread_self(), cur_rule->target);
		pthread_mutex_lock(&exec_mutex);
		fake_exec(cur_rule);
		pthread_mutex_unlock(&exec_mutex);
		add_rule(OUT_QUEUE, cur_rule);
	}

	//printf("Worker(%u) exiting\n", (unsigned int)pthread_self());
	return NULL;
}
Beispiel #2
0
void* helper_thread(void* args)
{
    //Unpack args
    ARG_HOLDER* argholder = (ARG_HOLDER*)(args);
    rule_node_t* queue = argholder->rule_queue;
    int queue_size = argholder->max_queue_length;
    argholder->threads_not_done++;
    int threadno = argholder->threads_not_done;
	int ql = queue_length(queue) - 1;
    while (!argholder->finished_adding || ql > 0)
    {
        //Check queue and "execute" targets on it
	    int full_queue = 0;
	    while (!argholder->done && ql == 0)
	    {
	        //Wait for the queue length to go up
	        cond_wait(&queue_empty, &mutex);
	        ql = queue_length(queue) - 1;
	    }
	    if (ql == queue_size)
	    {
	        full_queue = 1;
	    }
	    if (ql > 0 && !argholder->done)
        {
            //Remove the first target from the queue and "execute" it
            sem_wait(&sem_lock);
            rule_node_t* first_node = queue->next;
            rule_node_t* qnode = first_node->next;
            rule_t* cur_rule = first_node->rule;
            queue->next = qnode;
            free(first_node);
            sem_post(&sem_lock);
            //If the queue was full, signal the main thread that it is not
            if (full_queue)
            {
                pthread_cond_broadcast(&queue_full);
            }
            
            fake_exec(cur_rule);
            
            //Put rule on output queue
            rule_node_t* out_first = argholder->output_queue;
            rule_node_t* output = (rule_node_t*)malloc(sizeof(rule_node_t));
            output->rule = cur_rule;
            output->next = out_first;
            argholder->output_queue = output;
        }
        ql = queue_length(queue) - 1;
    }
    argholder->done = 1;
    argholder->threads_not_done--;
    pthread_cond_broadcast(&queue_empty);
    pthread_cond_signal(&finished_execution);
    //printf("Thread %d exiting.\n", threadno);
    return NULL;
}