From f449f278dd3c70e479a035f50a9bb817a9b433ba Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 17:24:08 +0200 Subject: Adding upstream version 3.2.6. Signed-off-by: Daniel Baumann --- tests/knot/test_worker_pool.c | 152 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 tests/knot/test_worker_pool.c (limited to 'tests/knot/test_worker_pool.c') diff --git a/tests/knot/test_worker_pool.c b/tests/knot/test_worker_pool.c new file mode 100644 index 0000000..59dee36 --- /dev/null +++ b/tests/knot/test_worker_pool.c @@ -0,0 +1,152 @@ +/* Copyright (C) 2021 CZ.NIC, z.s.p.o. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +#include + +#include +#include +#include +#include +#include + +#include "knot/worker/pool.h" +#include "knot/worker/queue.h" + +#define THREADS 4 +#define TASKS_BATCH 40 + +/*! + * Task execution log. + */ +typedef struct task_log { + pthread_mutex_t mx; + unsigned executed; +} task_log_t; + +/*! + * Get number of executed tasks and clear. + */ +static unsigned executed_reset(task_log_t *log) +{ + pthread_mutex_lock(&log->mx); + unsigned result = log->executed; + log->executed = 0; + pthread_mutex_unlock(&log->mx); + + return result; +} + +/*! + * Simple task, just increases the counter in the log. + */ +static void task_counting(worker_task_t *task) +{ + task_log_t *log = task->ctx; + + pthread_mutex_lock(&log->mx); + log->executed += 1; + pthread_mutex_unlock(&log->mx); +} + +static void interrupt_handle(int s) +{ +} + +int main(void) +{ + plan_lazy(); + + struct sigaction sa; + sa.sa_handler = interrupt_handle; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sigaction(SIGALRM, &sa, NULL); // Interrupt + + // create pool + + worker_pool_t *pool = worker_pool_create(THREADS); + ok(pool != NULL, "create worker pool"); + if (!pool) { + return 1; + } + + task_log_t log = { + .mx = PTHREAD_MUTEX_INITIALIZER, + }; + + // schedule jobs while pool is stopped + + worker_task_t task = { .run = task_counting, .ctx = &log }; + for (int i = 0; i < TASKS_BATCH; i++) { + worker_pool_assign(pool, &task); + } + + sched_yield(); + ok(executed_reset(&log) == 0, "executed count before start"); + + // start and wait for finish + + worker_pool_start(pool); + worker_pool_wait(pool); + ok(executed_reset(&log) == TASKS_BATCH, "executed count after start"); + + // add additional jobs while pool is running + + for (int i = 0; i < TASKS_BATCH; i++) { + worker_pool_assign(pool, &task); + } + + worker_pool_wait(pool); + ok(executed_reset(&log) == TASKS_BATCH, "executed count after add"); + + // temporary suspension + + worker_pool_suspend(pool); + + for (int i = 0; i < TASKS_BATCH; i++) { + worker_pool_assign(pool, &task); + } + + sched_yield(); + ok(executed_reset(&log) == 0, "executed count after suspend"); + + worker_pool_resume(pool); + worker_pool_wait(pool); + ok(executed_reset(&log) == TASKS_BATCH, "executed count after resume"); + + // try clean + + pthread_mutex_lock(&log.mx); + for (int i = 0; i < THREADS + TASKS_BATCH; i++) { + worker_pool_assign(pool, &task); + } + sched_yield(); + worker_pool_clear(pool); + pthread_mutex_unlock(&log.mx); + + worker_pool_wait(pool); + ok(executed_reset(&log) <= THREADS, "executed count after clear"); + + // cleanup + + worker_pool_stop(pool); + worker_pool_join(pool); + worker_pool_destroy(pool); + + pthread_mutex_destroy(&log.mx); + + return 0; +} -- cgit v1.2.3