static void * ThreadPool_work(void * arg) { ThreadInfo * work_th; ThreadPool * th_pool; work_th = (ThreadInfo*)arg; th_pool = work_th->th_pool; Queue_add(th_pool->curt_queue, NULL, work_th); if (work_th->job_func == NULL) { Queue_add(th_pool->idle_queue, NULL, work_th); } th_pool->pool_wait_need = FALSE; pthread_cond_signal(&(th_pool->pool_cond)); while ((!th_pool->pool_stop_need) && (!work_th->th_exit_need)) { if (work_th->job_func != NULL) { log_debug(log_cat, "------ job thread %u is running |", work_th->th_id); work_th->job_func(work_th->job_arg); work_th->job_func = NULL; work_th->job_arg = NULL; Queue_add(th_pool->idle_queue, NULL, work_th); } pthread_mutex_lock(&(work_th->th_lock)); log_debug(log_cat, "<<<<<< job thread %u start waiting |", work_th->th_id); //log_debug(log_cat, "<---<---<---<---<---<---<---<---<---<---<---<---<"); while (work_th->th_wait_need) pthread_cond_wait(&(work_th->th_cond), &(work_th->th_lock)); work_th->th_wait_need = TRUE; pthread_mutex_unlock(&(work_th->th_lock)); //log_debug(log_cat, ">--->--->--->--->--->--->--->--->--->--->--->--->"); log_debug(log_cat, ">>>>>> job thread %u end waiting |", work_th->th_id); } log_warn(log_cat, "job thread %u is going to exit", work_th->th_id); return NULL; }
static void test_Queue() { Queue* queue = Queue_new(); Consumer* consumers[NTHREADS_TOTAL]; int i_thread; for (i_thread = 0; i_thread < (NTHREADS_TOTAL / 2); i_thread++) consumers[i_thread] = Consumer_start(queue, i_thread, get_item); for (; i_thread < NTHREADS_TOTAL; i_thread++) consumers[i_thread] = Consumer_start(queue, i_thread, get_item_timed); PROFILE_BEGIN_FMT("Processing %d simple requests with %d threads\n", NITERATATIONS, NTHREADS_TOTAL); int i_item; int expected_sum = 0; for (i_item = 0; i_item < NITERATATIONS; i_item++) { int* x = cx_alloc(sizeof(int)); *x = i_item; Queue_add(queue, x); /* simulate submission delay */ expected_sum += i_item; #ifdef SUBMISSION_DELAY_MAX_MSEC usleep((rand() % SUBMISSION_DELAY_MAX_MSEC) * 1000); #endif } /* wait for threads to finish processing */ int total_processed = 0; for (i_thread = 0; i_thread < NTHREADS_TOTAL; i_thread++) { Consumer* consumer = consumers[i_thread]; // see http://stackoverflow.com/questions/5610677/valgrind-memory-leak-errors-when-using-pthread-create // http://stackoverflow.com/questions/5282099/signal-handling-in-pthreads pthread_join(*consumer->thread, NULL); XFLOG("Consumer[%d] processed %d", consumer->id, consumer->processed); total_processed += consumer->processed; Consumer_free(consumer); } PROFILE_END TEST_ASSERT_EQUAL(total_processed, NITERATATIONS); }
void Mutex_lock(MutexPtr mutex, PcbPtr pcb) { if (mutex == 0) return; // If someone currently owns the lock place them in the queue. if (mutex->owner != 0) { Queue_add(&mutex->waitingQueue, pcb); // If no one owns it then it's all yours... } else { mutex->owner = pcb->PID; } }