Path: blob/main/cddl/lib/libtpool/tests/libtpool_test.c
39488 views
#include <sys/stdtypes.h>1#include <sys/sysctl.h>2#include <errno.h>3#include <pthread.h>45#include <thread_pool.h>67#include <atf-c.h>89static void10tp_delay(void *arg)11{12pthread_barrier_t *barrier = arg;13int r;1415/* Block this task until all thread pool workers have been created. */16r = pthread_barrier_wait(barrier);17ATF_REQUIRE_MSG(r == 0 || r == PTHREAD_BARRIER_SERIAL_THREAD,18"pthread_barrier_wait failed: %s", strerror(r));19}2021/*22* NB: we could reduce the test's resource cost by using rctl(4). But that23* isn't enabled by default. And even with a thread limit of 1500, it takes <24* 0.1s to run on my machine. So I don't think it's worth optimizing for the25* case where rctl is available.26*/27ATF_TC(complete_exhaustion);28ATF_TC_HEAD(complete_exhaustion, tc)29{30atf_tc_set_md_var(tc, "descr",31"A thread pool should fail to schedule tasks if it is completely impossible to spawn any threads.");32}3334ATF_TC_BODY(complete_exhaustion, tc)35{36pthread_barrier_t barrier;37tpool_t *tp0, *tp1;38size_t len;39int max_threads_per_proc = 0;40int nworkers;41int r, i;4243len = sizeof(max_threads_per_proc);44r = sysctlbyname("kern.threads.max_threads_per_proc",45&max_threads_per_proc, &len, NULL, 0);46ATF_REQUIRE_EQ_MSG(r, 0, "sysctlbyname: %s", strerror(errno));47nworkers = max_threads_per_proc - 1;48pthread_barrier_init(&barrier, NULL, max_threads_per_proc);4950/*51* Create the first thread pool and spawn the maximum allowed number of52* processes.53*/54tp0 = tpool_create(nworkers, nworkers, 1, NULL);55ATF_REQUIRE(tp0 != NULL);56for (i = 0; i < nworkers; i++) {57ATF_REQUIRE_EQ(tpool_dispatch(tp0, tp_delay, &barrier), 0);58}5960/*61* Now create a second thread pool. Unable to create new threads, the62* dispatch function should return an error.63*/64tp1 = tpool_create(nworkers, 2 * nworkers, 1, NULL);65ATF_REQUIRE(tp1 != NULL);66ATF_REQUIRE_EQ(tpool_dispatch(tp1, tp_delay, NULL), -1);6768/* Cleanup */69r = pthread_barrier_wait(&barrier);70ATF_REQUIRE_MSG(r == 0 || r == PTHREAD_BARRIER_SERIAL_THREAD,71"pthread_barrier_wait failed: %s", strerror(r));72tpool_wait(tp1);73tpool_wait(tp0);74}7576ATF_TP_ADD_TCS(tp)77{78ATF_TP_ADD_TC(tp, complete_exhaustion);7980return (atf_no_error());81}828384