pony_ctx_t* ponyint_sched_init(uint32_t threads, bool noyield, bool nopin, bool pinasio) { use_yield = !noyield; // If no thread count is specified, use the available physical core count. if(threads == 0) threads = ponyint_cpu_count(); scheduler_count = threads; scheduler = (scheduler_t*)ponyint_pool_alloc_size( scheduler_count * sizeof(scheduler_t)); memset(scheduler, 0, scheduler_count * sizeof(scheduler_t)); uint32_t asio_cpu = ponyint_cpu_assign(scheduler_count, scheduler, nopin, pinasio); for(uint32_t i = 0; i < scheduler_count; i++) { scheduler[i].ctx.scheduler = &scheduler[i]; scheduler[i].last_victim = &scheduler[i]; ponyint_messageq_init(&scheduler[i].mq); ponyint_mpmcq_init(&scheduler[i].q); } this_scheduler = &scheduler[0]; ponyint_mpmcq_init(&inject); ponyint_asio_init(asio_cpu); return &scheduler[0].ctx; }
asio_backend_t* ponyint_asio_backend_init() { asio_backend_t* b = POOL_ALLOC(asio_backend_t); memset(b, 0, sizeof(asio_backend_t)); ponyint_messageq_init(&b->q); b->epfd = epoll_create1(EPOLL_CLOEXEC); b->wakeup = eventfd(0, EFD_NONBLOCK); if(b->epfd == 0 || b->wakeup == 0) { POOL_FREE(asio_backend_t, b); return NULL; } struct epoll_event ep; ep.data.ptr = b; ep.events = EPOLLIN | EPOLLRDHUP | EPOLLET; epoll_ctl(b->epfd, EPOLL_CTL_ADD, b->wakeup, &ep); return b; }
asio_backend_t* ponyint_asio_backend_init() { asio_backend_t* b = POOL_ALLOC(asio_backend_t); memset(b, 0, sizeof(asio_backend_t)); ponyint_messageq_init(&b->q); b->epfd = epoll_create1(EPOLL_CLOEXEC); b->wakeup = eventfd(0, EFD_NONBLOCK); if(b->epfd == 0 || b->wakeup == 0) { POOL_FREE(asio_backend_t, b); return NULL; } struct epoll_event ep; ep.data.ptr = b; ep.events = EPOLLIN | EPOLLRDHUP | EPOLLET; epoll_ctl(b->epfd, EPOLL_CTL_ADD, b->wakeup, &ep); #if !defined(USE_SCHEDULER_SCALING_PTHREADS) // Make sure we ignore signals related to scheduler sleeping/waking // as the default for those signals is termination struct sigaction new_action; new_action.sa_handler = empty_signal_handler; sigemptyset (&new_action.sa_mask); // ask to restart interrupted syscalls to match `signal` behavior new_action.sa_flags = SA_RESTART; sigaction(PONY_SCHED_SLEEP_WAKE_SIGNAL, &new_action, NULL); #endif return b; }