int main(int argc, char **argv) { uint8_t sz2 = 12; uint8_t max_threads = 8; char *sz2_env = getenv("SZ2"); char *max_threads_env = getenv("MAX_THREADS"); if (sz2_env) { sz2 = atoi(sz2_env); } if (max_threads_env) { max_threads = atoi(max_threads_env); } struct threadpool_config cfg = { .task_ringbuf_size2 = sz2, .max_threads = max_threads, }; struct threadpool *t = Threadpool_Init(&cfg); assert(t); struct threadpool_task task = { .task = task_cb, .udata = t, }; struct threadpool_info stats; struct timeval tv; gettimeofday(&tv, NULL); time_t last_sec = tv.tv_sec; size_t counterpressure = 0; size_t ticks = 0; for (;;) { gettimeofday(&tv, NULL); if (tv.tv_sec > last_sec) { last_sec = tv.tv_sec; Threadpool_Stats(t, &stats); ticks++; dump_stats("tick...", &stats, ticks); } /* Every 16 seconds, pause scheduling for 5 seconds to test * thread sleep/wake-up alerts. */ if ((ticks & 15) == 0) { sleep(5); } for (size_t i = 0; i < 1000; i++) { if (!Threadpool_Schedule(t, &task, &counterpressure)) { size_t msec = i * 1000 * counterpressure; usleep(msec >> 12); } else { break; } }
static void task_cb(void *udata) { struct threadpool *t = (struct threadpool *)udata; for (;;) { if (ATOMIC_BOOL_COMPARE_AND_SWAP(&task_count, task_count, task_count + 1)) { break; } } size_t arg = task_count; arg = 30 + (random() % 10); size_t tc = task_count; size_t res = fibs(arg); printf("%zd -- fibs(%zd) => %zd", tc, arg, res); struct threadpool_info stats; Threadpool_Stats(t, &stats); dump_stats("", &stats); }
int main(int argc, char **argv) { uint8_t sz2 = 8; uint8_t max_threads = 8; char *sz2_env = getenv("SZ2"); char *max_threads_env = getenv("MAX_THREADS"); if (sz2_env) { sz2 = atoi(sz2_env); } if (max_threads_env) { max_threads = atoi(max_threads_env); } struct threadpool_config cfg = { .task_ringbuf_size2 = sz2, .max_threads = max_threads, }; struct threadpool *t = Threadpool_Init(&cfg); assert(t); struct threadpool_task task = { .task = task_cb, .udata = t, }; struct threadpool_info stats; for (int i = 0; i < 4; i++) { printf("scheduling...\n"); for (int j = 0; j < 40; j++) { for (;;) { size_t counterpressure = 0; if (Threadpool_Schedule(t, &task, &counterpressure)) { break; } else { size_t msec = 10 * 1000 * counterpressure; usleep(msec); } } } Threadpool_Stats(t, &stats); dump_stats("sleeping...", &stats); sleep(1); Threadpool_Stats(t, &stats); dump_stats("waking...", &stats); } while (task_count < 4 * 40) { sleep(1); } task.task = inf_loop_cb; size_t counterpressure = 0; while (!Threadpool_Schedule(t, &task, &counterpressure)) { usleep(10 * 1000); } sleep(1); const int THREAD_SHUTDOWN_SECONDS = 5; printf("shutting down...\n"); int limit = (1000 * THREAD_SHUTDOWN_SECONDS)/10; for (int i = 0; i < limit; i++) { if (Threadpool_Shutdown(t, false)) { break; } (void)poll(NULL, 0, 10); if (i == limit - 1) { printf("cancelling thread in intentional infinite loop\n"); Threadpool_Shutdown(t, true); } } Threadpool_Free(t); return 0; }