Beispiel #1
0
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;
}
Beispiel #2
0
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();
    
}
Beispiel #3
0
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;
}
Beispiel #4
0
    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();
    }
Beispiel #5
0
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);
}
Beispiel #6
0
/*
 * 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);
}