static void engine_create_drudgers(engine_type* engine) { size_t i = 0; ods_log_assert(engine); ods_log_assert(engine->config); CHECKALLOC(engine->drudgers = (worker_type**) malloc(((size_t)engine->config->num_signer_threads) * sizeof(worker_type*))); for (i=0; i < (size_t) engine->config->num_signer_threads; i++) { engine->drudgers[i] = worker_create(i, WORKER_DRUDGER); } }
void pool_start(struct thread_pool *pool, uint32_t threads) { PRINT_DEBUG("Entered: pool=%p, threads=%u", pool, threads); int i; struct pool_worker *worker; for (i = 0; i < threads; i++) { worker = worker_create(&pool->inactive_sem, &pool->inactive_num, pool->queue, ++pool->worker_count); list_append(pool->workers, worker); } PRINT_DEBUG("Exited: pool=%p, len=%u", pool, pool->workers->len); }
/** * Allocate empty worker structures. With backptr and thread-number, * from 0..numthread initialised. Used as user arguments to new threads. * Creates the daemon random generator if it does not exist yet. * The random generator stays existing between reloads with a unique state. * @param daemon: the daemon with (new) config settings. */ static void daemon_create_workers(struct daemon* daemon) { int i, numport; int* shufport; log_assert(daemon && daemon->cfg); if(!daemon->rand) { unsigned int seed = (unsigned int)time(NULL) ^ (unsigned int)getpid() ^ 0x438; daemon->rand = ub_initstate(seed, NULL); if(!daemon->rand) fatal_exit("could not init random generator"); hash_set_raninit((uint32_t)ub_random(daemon->rand)); } shufport = (int*)calloc(65536, sizeof(int)); if(!shufport) fatal_exit("out of memory during daemon init"); numport = daemon_get_shufport(daemon, shufport); verbose(VERB_ALGO, "total of %d outgoing ports available", numport); daemon->num = (daemon->cfg->num_threads?daemon->cfg->num_threads:1); if(daemon->reuseport && (int)daemon->num < (int)daemon->num_ports) { log_warn("cannot reduce num-threads to %d because so-reuseport " "so continuing with %d threads.", (int)daemon->num, (int)daemon->num_ports); daemon->num = (int)daemon->num_ports; } daemon->workers = (struct worker**)calloc((size_t)daemon->num, sizeof(struct worker*)); if(!daemon->workers) fatal_exit("out of memory during daemon init"); if(daemon->cfg->dnstap) { #ifdef USE_DNSTAP daemon->dtenv = dt_create(daemon->cfg->dnstap_socket_path, (unsigned int)daemon->num); if (!daemon->dtenv) fatal_exit("dt_create failed"); dt_apply_cfg(daemon->dtenv, daemon->cfg); #else fatal_exit("dnstap enabled in config but not built with dnstap support"); #endif } for(i=0; i<daemon->num; i++) { if(!(daemon->workers[i] = worker_create(daemon, i, shufport+numport*i/daemon->num, numport*(i+1)/daemon->num - numport*i/daemon->num))) /* the above is not ports/numthr, due to rounding */ fatal_exit("could not create worker"); } free(shufport); }
static void engine_create_drudgers(engine_type* engine) { size_t i = 0; ods_log_assert(engine); ods_log_assert(engine->config); ods_log_assert(engine->allocator); engine->drudgers = (worker_type**) allocator_alloc(engine->allocator, ((size_t)engine->config->num_signer_threads) * sizeof(worker_type*)); for (i=0; i < (size_t) engine->config->num_signer_threads; i++) { engine->drudgers[i] = worker_create(engine->allocator, i, WORKER_DRUDGER); } return; }
TPOOL_RTN_E tpool_create(struct tpool_ctx ** obj, uint8_t num) { int i; struct tpool_ctx * tpool = NULL; if ((tpool = malloc(sizeof(struct tpool_ctx))) == NULL) return TPOOL_FAILED; memset(tpool, 0, sizeof(struct tpool_ctx)); tpool->workers_num_total = 0; tpool->workers_num_running = 0; tpool->workers_num_working = 0; tpool->keep_alive = 0; pthread_mutex_init(&tpool->workers_num_lock, NULL); pthread_cond_init(&tpool->workers_idle_cond, NULL); pthread_mutex_init(&tpool->tasks_uid_lock, NULL); // Initial tasks if (qlist_create(&tpool->tasks) != QLIST_SUCCESS) { tpool_destroy(tpool); return TPOOL_FAILED; } // Initial workers array tpool->workers = (struct tpool_worker **) malloc(sizeof(struct tpool_worker *) * num); if (tpool->workers == NULL) { tpool_destroy(tpool); return TPOOL_FAILED; } // Initial all workers for (i = 0; i < num; i++) { if (worker_create(&tpool->workers[i]) != TPOOL_SUCCESS) { tpool_destroy(tpool); return TPOOL_FAILED; } tpool->workers[i]->uid = 0; tpool->workers[i]->tpool = tpool; tpool->workers_num_total++; } *obj = tpool; return TPOOL_SUCCESS; }
void create_worker_system(int count) { int i; pthread_t tid; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); for (i=0; i<count; i++) { g_ppworker[i] = worker_create(); if (pthread_create(&tid, &attr, worker_loop, (void *)g_ppworker[i]) != 0) { print_log(LOG_TYPE_ERROR, "create work thread error"); pthread_attr_destroy(&attr); return; } pthread_attr_destroy(&attr); } }
int pool_execute(struct thread_pool *pool, void *(*work)(void *local), void *local) { PRINT_DEBUG("Entered: pool=%p, work=%p, local=%p", pool, work, local); secure_sem_wait(&pool->inactive_sem); PRINT_DEBUG("inactive_num=%u", pool->inactive_num); if (pool->inactive_num) { struct pool_worker *worker = (struct pool_worker *) list_find(pool->workers, worker_inactive_test); PRINT_DEBUG("found worker=%p", worker); if (worker != NULL) { pool->inactive_num--; worker->inactive = 0; worker->work = work; worker->local = local; PRINT_DEBUG("activating: worker=%p, inactive_num=%u", worker, *worker->inactive_num); sem_post(&worker->activate_sem); sem_post(&pool->inactive_sem); return 1; } else { PRINT_WARN("todo error"); sem_post(&pool->inactive_sem); //TODO shouldn't be possible return 0; } } else { //TODO change to simply queue it, have controller optimize pool size //TODO have execute change queue size? if (list_has_space(pool->queue)) { struct pool_request *request = (struct pool_request *) secure_malloc(sizeof(struct pool_request)); request->work = work; request->local = local; list_append(pool->queue, request); sem_post(&pool->inactive_sem); return 1; } else { sem_post(&pool->inactive_sem); return 0; } if (0) { if (list_has_space(pool->workers)) { PRINT_DEBUG("Starting new worker"); struct pool_worker *worker = worker_create(&pool->inactive_sem, &pool->inactive_num, pool->queue, pool->worker_count++); list_append(pool->workers, worker); worker->work = work; worker->local = local; PRINT_DEBUG("activating: worker=%p, inactive_num=%u", worker, *worker->inactive_num); sem_post(&worker->activate_sem); sem_post(&pool->inactive_sem); //TODO wait? or do the find function again? etc preload it. return 1; } else { sem_post(&pool->inactive_sem); //TODO queue it? have finishing threads check queue? return 0; } } } }