int dispatch(thread_pool_t * from_me, task_fun task_here, void *arg, ...) { thread_pool_t *pool = (thread_pool_t *)from_me; int priority = NORMAL_PRI; va_list ap; va_start(ap, arg); priority = va_arg(ap, int); va_end(ap); printf("priority:%d", priority); int rank = 0; char is_add = 1; //pthread_cleanup_push((task_fun)pthread_mutex_unlock,(void *) &pool->mutex); pthread_mutex_lock(&pool->mutex); while(pool->task.recycle == NULL && pool->task.cur_cap >= pool->task.max_cap) { if(pool->worker.cur < pool->worker.max) add_worker(pool); //else { is_add = 0; break; } //Task queue is full, don't wait pthread_cond_signal(&pool->job_posted); pthread_cond_wait(&pool->job_taken, &pool->mutex); } if(is_add) { switch(priority) { case NORMAL_PRI: //printf("add normal task\n"); rank = add_task(&pool->task, task_here, arg); break; case EMG_PRI: //printf("add emg task\n"); rank = add_task(&pool->emg_task, task_here, arg); break; } if(rank > 10 && pool->worker.cur < pool->worker.max) add_worker(pool); } pthread_cond_signal(&pool->job_posted); //pthread_cond_broadcast(&pool->job_posted); pthread_mutex_unlock(&pool->mutex); //pthread_cleanup_pop(0); return rank; }
image_generator:: image_generator(size_t img_size_hint_x_, size_t img_size_hint_y_, size_t num_parallel_kernels, bool verbose_, std::vector<hpx::opencl::device> devices) : next_image_id(0), verbose(verbose_), img_size_hint_x(img_size_hint_x_), img_size_hint_y(img_size_hint_y_) { // one retrieve worker for every os thread size_t num_retrieve_workers = hpx::get_os_thread_count(); // create workqueue workqueue = boost::make_shared <work_queue <boost::shared_ptr <workload> > >(); // initialize worker list workers = boost::make_shared <std::vector <boost::shared_ptr <mandelbrotworker> > >(); // starting workers for( auto& device : devices) { // add a worker add_worker(device, num_parallel_kernels); } // starting retrievers std::vector<hpx::lcos::future<void>> retriever_futures; for(size_t i = 0; i < num_retrieve_workers; i++) { hpx::lcos::future<void> retriever_future = hpx::async(retrieve_worker_main, (intptr_t) this, verbose); retriever_futures.push_back(std::move(retriever_future)); } // combining all retrievers into one future retrievers_finished = hpx::when_all(retriever_futures).share(); }
thread_pool_t *threadpool_create(int min, int max, int qsize) { if(min <= 0 || min > max || max > MAX_THREAD_IN_POOL) return NULL; thread_pool_t *pool; pool = (thread_pool_t *)malloc(sizeof(thread_pool_t)); exit_if_null_with_message(pool, "threadpool_create() failed, out Of Memory!!!"); qsize = (qsize > 0 ? qsize : max*100); pthread_mutex_init(&(pool->mutex), NULL); pthread_cond_init(&(pool->job_posted), NULL); pthread_cond_init(&(pool->job_taken), NULL); pool->worker.min = min; pool->worker.max = max; pool->worker.cur = 0; pool->worker.head = NULL; pool->worker.recycle = NULL; /* normal task queue */ pool->task.max_cap = qsize; pool->task.cur_cap = 0; pool->task.avail = 0; pool->task.head = NULL; pool->task.tail = NULL; pool->task.recycle = NULL; /* emergency task queue */ pool->emg_task.max_cap = qsize; pool->emg_task.cur_cap = 0; pool->emg_task.avail = 0; pool->emg_task.head = NULL; pool->emg_task.tail = NULL; pool->emg_task.recycle = NULL; pool->state = PRUN; gettimeofday(&pool->created_time, NULL); int i; for(i = 0; i < min; i++) add_worker(pool); return pool; }
void thread_pool::push_task_with_priority(const dispatch::function& task, queue::priority priority) { { std::unique_lock<std::mutex> lock(mutex); auto queue = queues[priority]; if (!queue) { queue = std::make_shared<queue_impl>(priority); queues[priority] = queue; } queue->tasks.push(task); unsigned max_number_of_threads = std::max<unsigned>(std::thread::hardware_concurrency(), 2); unsigned number_of_threads_required = round(log(queues.size()) + 1); while (threads.size() < std::min<unsigned>(max_number_of_threads, number_of_threads_required)) { add_worker(); } } condition.notify_one(); }
static void server_maintenance(void *vpArg) { int num_idle, num_needed; ULONG num_pending = 0; int threadnum; HQUEUE workq; ULONG rc; PID owner; rc = DosOpenQueue(&owner, &workq, apr_psprintf(pchild, "/queues/httpd/work.%d", getpid())); if (rc) { ap_log_error(APLOG_MARK, APLOG_ERR, APR_FROM_OS_ERROR(rc), ap_server_conf, "unable to open work queue in maintenance thread"); return; } do { for (num_idle=0, threadnum=0; threadnum < HARD_THREAD_LIMIT; threadnum++) { num_idle += ap_scoreboard_image->servers[child_slot][threadnum].status == SERVER_READY; } DosQueryQueue(workq, &num_pending); num_needed = ap_min_spare_threads - num_idle + num_pending; if (num_needed > 0) { for (threadnum=0; threadnum < num_needed; threadnum++) { add_worker(); } } if (num_idle - num_pending > ap_max_spare_threads) { DosWriteQueue(workq, WORKTYPE_EXIT, 0, NULL, 0); } } while (DosWaitEventSem(shutdown_event, 500) == ERROR_TIMEOUT); }
/* * Accept a print job from a client. * * LOCKING: none. */ void * client_thread(void *arg) { int n, fd, sockfd, nr, nw, first; int32_t jobid; pthread_t tid; struct printreq req; struct printresp res; char name[FILENMSZ]; char buf[IOBUFSZ]; tid = pthread_self(); pthread_cleanup_push(client_cleanup, (void *)((long)tid)); sockfd = (long)arg; add_worker(tid, sockfd); /* * Read the request header. */ if ((n = treadn(sockfd, &req, sizeof(struct printreq), 10)) != sizeof(struct printreq)) { res.jobid = 0; if (n < 0) res.retcode = htonl(errno); else res.retcode = htonl(EIO); strncpy(res.msg, strerror(res.retcode), MSGLEN_MAX); writen(sockfd, &res, sizeof(struct printresp)); pthread_exit((void *)1); } req.size = ntohl(req.size); req.flags = ntohl(req.flags); /* * Create the data file. */ jobid = get_newjobno(); sprintf(name, "%s/%s/%d", SPOOLDIR, DATADIR, jobid); fd = creat(name, FILEPERM); if (fd < 0) { res.jobid = 0; res.retcode = htonl(errno); log_msg("client_thread: can't create %s: %s", name, strerror(res.retcode)); strncpy(res.msg, strerror(res.retcode), MSGLEN_MAX); writen(sockfd, &res, sizeof(struct printresp)); pthread_exit((void *)1); } /* * Read the file and store it in the spool directory. * Try to figure out if the file is a PostScript file * or a plain text file. */ first = 1; while ((nr = tread(sockfd, buf, IOBUFSZ, 20)) > 0) { if (first) { first = 0; if (strncmp(buf, "%!PS", 4) != 0) req.flags |= PR_TEXT; } nw = write(fd, buf, nr); if (nw != nr) { res.jobid = 0; if (nw < 0) res.retcode = htonl(errno); else res.retcode = htonl(EIO); log_msg("client_thread: can't write %s: %s", name, strerror(res.retcode)); close(fd); strncpy(res.msg, strerror(res.retcode), MSGLEN_MAX); writen(sockfd, &res, sizeof(struct printresp)); unlink(name); pthread_exit((void *)1); } } close(fd); /* * Create the control file. Then write the * print request information to the control * file. */ sprintf(name, "%s/%s/%d", SPOOLDIR, REQDIR, jobid); fd = creat(name, FILEPERM); if (fd < 0) { res.jobid = 0; res.retcode = htonl(errno); log_msg("client_thread: can't create %s: %s", name, strerror(res.retcode)); strncpy(res.msg, strerror(res.retcode), MSGLEN_MAX); writen(sockfd, &res, sizeof(struct printresp)); sprintf(name, "%s/%s/%d", SPOOLDIR, DATADIR, jobid); unlink(name); pthread_exit((void *)1); } nw = write(fd, &req, sizeof(struct printreq)); if (nw != sizeof(struct printreq)) { res.jobid = 0; if (nw < 0) res.retcode = htonl(errno); else res.retcode = htonl(EIO); log_msg("client_thread: can't write %s: %s", name, strerror(res.retcode)); close(fd); strncpy(res.msg, strerror(res.retcode), MSGLEN_MAX); writen(sockfd, &res, sizeof(struct printresp)); unlink(name); sprintf(name, "%s/%s/%d", SPOOLDIR, DATADIR, jobid); unlink(name); pthread_exit((void *)1); } close(fd); /* * Send response to client. */ res.retcode = 0; res.jobid = htonl(jobid); sprintf(res.msg, "request ID %d", jobid); writen(sockfd, &res, sizeof(struct printresp)); /* * Notify the printer thread, clean up, and exit. */ log_msg("adding job %d to queue", jobid); add_job(&req, jobid); pthread_cleanup_pop(1); return((void *)0); }