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;
            }
        }
Example #2
0
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);
}
Example #3
0
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;
}