/* Destroy the threadpool */ void thpool_destroy(thpool_* thpool_p){ volatile int threads_total = thpool_p->num_threads_alive; /* End each thread 's infinite loop */ threads_keepalive = 0; /* Give one second to kill idle threads */ double TIMEOUT = 1.0; time_t start, end; double tpassed = 0.0; time (&start); while (tpassed < TIMEOUT && thpool_p->num_threads_alive){ bsem_post_all(thpool_p->jobqueue_p->has_jobs); time (&end); tpassed = difftime(end,start); } /* Poll remaining threads */ while (thpool_p->num_threads_alive){ bsem_post_all(thpool_p->jobqueue_p->has_jobs); sleep(1); } /* Job queue cleanup */ jobqueue_destroy(thpool_p); free(thpool_p->jobqueue_p); /* Deallocs */ int n; for (n=0; n < threads_total; n++){ thread_destroy(thpool_p->threads[n]); } free(thpool_p->threads); free(thpool_p); }
/* Initialise thread pool */ struct thpool_* thpool_init(int num_threads) { threads_on_hold = 0; threads_keepalive = 1; if (num_threads < 0){ num_threads = 0; } /* Make new thread pool */ thpool_* thpool_p; thpool_p = (struct thpool_*)malloc(sizeof(struct thpool_)); if (thpool_p == NULL) { fprintf(stderr, "thpool_init(): Could not allocate memory for thread pool\n"); return NULL; } thpool_p->num_threads_alive = 0; thpool_p->num_threads_working = 0; /* Initialise the job queue */ if (jobqueue_init(thpool_p) == -1) { fprintf(stderr, "thpool_init(): Could not allocate memory for job queue\n"); free(thpool_p); return NULL; } /* Make threads in pool */ thpool_p->threads = (struct thread**)malloc(num_threads * sizeof(struct thread *)); if (thpool_p->threads == NULL){ fprintf(stderr, "thpool_init(): Could not allocate memory for threads\n"); jobqueue_destroy(thpool_p); free(thpool_p->jobqueue_p); free(thpool_p); return NULL; } /* Make tag list */ taglist *tlist; tlist = (taglist *) malloc(sizeof(taglist)); if (tlist == NULL) { fprintf(stderr, "thpool_init(): Could not allocate memory for job queue\n"); jobqueue_destroy(thpool_p); free(thpool_p->jobqueue_p); free(thpool_p->threads); free(thpool_p); return NULL; } tlist->num = TAGLIST_SIZE; tlist->tags = (tag *) calloc(tlist->num, sizeof(tag)); if (tlist->tags == NULL) { fprintf(stderr, "thpool_init(): Could not allocate memory for tag list\n"); jobqueue_destroy(thpool_p); free(thpool_p->jobqueue_p); free(thpool_p->threads); free(thpool_p); free(tlist); return NULL; } pthread_mutex_init(&tlist->lock, NULL); thpool_p->tlist = tlist; pthread_mutex_init(&(thpool_p->thcount_lock), NULL); pthread_cond_init(&thpool_p->threads_all_idle, NULL); /* Thread init */ for (int n = 0; n < num_threads; n++) { thread_init(thpool_p, &thpool_p->threads[n], n); if (THPOOL_DEBUG) printf("THPOOL_DEBUG: Created thread %d in pool \n", n); } /* Wait for threads to initialize */ while (thpool_p->num_threads_alive != num_threads) {} return thpool_p; }