示例#1
0
/*!
 * \brief Add threads to the threadpool
 *
 * This function is called from the threadpool's control taskprocessor thread.
 * \param pool The pool that is expanding
 * \delta The number of threads to add to the pool
 */
static void grow(struct ast_threadpool *pool, int delta)
{
	int i;

	int current_size = ao2_container_count(pool->active_threads) +
		ao2_container_count(pool->idle_threads);

	if (pool->options.max_size && current_size + delta > pool->options.max_size) {
		delta = pool->options.max_size - current_size;
	}

	ast_debug(3, "Increasing threadpool %s's size by %d\n",
			ast_taskprocessor_name(pool->tps), delta);

	for (i = 0; i < delta; ++i) {
		struct worker_thread *worker = worker_thread_alloc(pool);
		if (!worker) {
			return;
		}
		if (ao2_link(pool->idle_threads, worker)) {
			if (worker_thread_start(worker)) {
				ast_log(LOG_ERROR, "Unable to start worker thread %d. Destroying.\n", worker->id);
				ao2_unlink(pool->active_threads, worker);
			}
		} else {
			ast_log(LOG_WARNING, "Failed to activate worker thread %d. Destroying.\n", worker->id);
		}
		ao2_ref(worker, -1);
	}
}
示例#2
0
文件: prm.c 项目: FreifeldRoyi/vmsim
errcode_t prm_init(mmu_t* mmu)
{
	errcode_t errcode;
	DEBUG("PRM starting\n");
	pthread_mutex_init(&prm_mutex,NULL);
	pthread_mutex_init(&prm_queue_mutex,NULL);
	pthread_cond_init(&prm_queue_condvar, NULL);

	pthread_cond_init(&prm_condvar, NULL);
	prm_queue = queue_init();
	if (prm_queue == NULL)
		return ecFail;

	errcode = worker_thread_create(&prm_thread, prm_thread_func);
	if (errcode != ecSuccess)
	{
		return errcode;
	}

	errcode = worker_thread_start(&prm_thread, mmu);
	if (errcode != ecSuccess)
	{
		return errcode;
	}

	return ecSuccess;
}
示例#3
0
errcode_t aging_daemon_start(mmu_t* mmu)
{
	errcode_t errcode;

	errcode = worker_thread_create(&daemon_thread, &daemon_func);
	if (errcode != ecSuccess)
	{
		return errcode;
	}

	pthread_mutex_init(&daemon_mutex, NULL);
	pthread_cond_init(&should_update_condvar, NULL);
	pthread_cond_init(&done_updating_condvar, NULL);

	should_update = FALSE;

	errcode = worker_thread_start(&daemon_thread, mmu);
	if (errcode != ecSuccess)
	{
		return errcode;
	}

	return ecSuccess;
}
示例#4
0
static 
int 
server_init(
    struct server* p_srv
    )
{
  assert(p_srv);
  memset(p_srv, 0, sizeof(*p_srv));

  p_srv->sv_allocator = allocator_handle;
  p_srv->sv_quitflag = 0;
  p_srv->sv_acceptfd = create_server_socket();
  if (-1 == p_srv->sv_acceptfd) {
    return -1;
  }
  /*
   * Level 1 - accept socket created.
   */
  ++p_srv->sv_rollback;

  p_srv->sv_epollfd = epoll_create(kMaxEpollCompletionEntries);
  if (-1 == p_srv->sv_epollfd) {
    return -1;
  }
  /*
   * Level 2 - epoll descriptor allocated.
   */
  ++p_srv->sv_rollback;

  /*
   * Block SIGINT and create a signal descriptor to receive it via epoll.
   */
  sigset_t sig_mask;
  sigemptyset(&sig_mask);
  if (-1 == sigaddset(&sig_mask, SIGINT)) {
    return -1;
  }
  if (-1 == sigprocmask(SIG_BLOCK, &sig_mask, NULL)) {
    return -1;
  }
  p_srv->sv_sigfds = signalfd(-1, &sig_mask, SFD_NONBLOCK);
  if (-1 == p_srv->sv_sigfds) {
    return -1;
  }
  /*
   * Level 3 - signal descriptor for SIGINT allocated.
   */
  ++p_srv->sv_rollback;

  /*
   * Add termination signal and accept socket to epoll interface.
   */
  if (-1 == add_fd_to_epoll(p_srv->sv_epollfd,
                            p_srv->sv_sigfds,
                            EPOLLIN | EPOLLET,
                            kDataTypeFD,
                            p_srv->sv_sigfds)) {
    return -1;
  }

  if (-1 == add_fd_to_epoll(p_srv->sv_epollfd,
                            p_srv->sv_acceptfd,
                            EPOLLIN | EPOLLET | EPOLLRDHUP,
                            kDataTypeFD,
                            p_srv->sv_acceptfd)) {
    return -1;
  }

  p_srv->sv_threadrdy_eventfds = eventfd(0, 0);
  if (p_srv->sv_threadrdy_eventfds == -1) {
    D_FUNCFAIL_ERRNO(eventfd);
    return -1;
  }
  /*
   * Level 4 - thread notification event created.
   */
  ++p_srv->sv_rollback;

  /*
   * Get number of available processors. The number of spawned threads is
   * nr_processors * thread_to_proc_ratio.
   */
  long nr_procs = sysconf(_SC_NPROCESSORS_ONLN);
  if (nr_procs == -1) {
    D_FUNCFAIL_ERRNO(sysconf);
    return -1;
  }
  D_FMTSTRING("Online processors %d, will spawn %d threads.",
              nr_procs, nr_procs);

  p_srv->sv_workers = p_srv->sv_allocator->al_mem_alloc(
      p_srv->sv_allocator, (sizeof(struct worker_thread*) * nr_procs));
  if (!p_srv->sv_workers) {
    D_FMTSTRING("Out of memory!");
    return -1;
  }
  /*
   * Level 5 - memory for worker thread data allocated.
   */
  ++p_srv->sv_rollback;
  memset(p_srv->sv_workers, 0, sizeof(struct worker_thread*) * nr_procs);

  /*
   * Initialize data and start worker threads.
   */
  for (long l = 0; l < nr_procs; ++l) {
    char thread_msgqueue[NAME_MAX];
    snprintf(thread_msgqueue, sizeof(thread_msgqueue) - 1, 
             "/__msgqueue_thread_%d__", (int) l);
    struct worker_thread* current = worker_thread_create(thread_msgqueue, 
                                                         p_srv->sv_allocator);
    if (current) {
      if (worker_thread_start(p_srv, current, NULL) == 0) {
        /*
         * Thread successfully initialized, add it to list.
         */
        p_srv->sv_workers[p_srv->sv_worker_count++] = current;
      } else {
        /*
         * Cleanup thread data since pthread_create() failed.
         */
        worker_thread_destroy(current);
      }
    }
  }
  if (!p_srv->sv_worker_count) {
    D_FMTSTRING("Fatal : failed to initialize at least one worker thread!");
    return -1;
  }

  D_FMTSTRING("Started a total of %d worker threads", p_srv->sv_worker_count);
  /*
   * Server is up and running.
   */
  return 0;
}