summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Gianforcaro <b.gianfo@gmail.com>2020-04-26 02:50:48 -0700
committerAndreas Kling <kling@serenityos.org>2020-04-26 21:31:52 +0200
commit60fc939e81cf2968884d73c55db79773887737f5 (patch)
tree4937dd4ce68f77ac99e8f3308985a17bc7b4c33a
parent6116739b38b7d7c1f0195a395e3885782cb78974 (diff)
downloadserenity-60fc939e81cf2968884d73c55db79773887737f5.zip
Tests: Add test case for pthread_cond_timedwait with a timeout.
Add a test case that the timeout argument to pthread_cond_timedwait works in LibPthread. This change also validates the new support for timeouts to the futex syscall, as that's how condition variables are implemented.
-rw-r--r--Tests/Kernel/pthread-cond-timedwait-example.cpp71
1 files changed, 71 insertions, 0 deletions
diff --git a/Tests/Kernel/pthread-cond-timedwait-example.cpp b/Tests/Kernel/pthread-cond-timedwait-example.cpp
new file mode 100644
index 0000000000..2a5e2109c0
--- /dev/null
+++ b/Tests/Kernel/pthread-cond-timedwait-example.cpp
@@ -0,0 +1,71 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <errno.h>
+#include <unistd.h>
+#include <ctime>
+#include <cstring>
+#include <cassert>
+
+struct worker_t
+{
+ const char* name;
+ int count;
+ pthread_t thread;
+ pthread_mutex_t lock;
+ pthread_cond_t cond;
+ long int wait_time;
+};
+
+void* run_worker(void* args)
+{
+ struct timespec time_to_wait = {0, 0};
+ worker_t* worker = (worker_t*)args;
+ worker->count = 0;
+
+ while (worker->count < 25) {
+ time_to_wait.tv_sec = time(nullptr) + worker->wait_time;
+ pthread_mutex_lock(&worker->lock);
+ int rc = pthread_cond_timedwait(&worker->cond, &worker->lock, &time_to_wait);
+
+ // Validate return code is always timed out.
+ assert(rc == -1);
+ assert(errno == ETIMEDOUT);
+
+ worker->count++;
+ printf("Increase worker[%s] count to [%d]\n", worker->name, worker->count);
+ pthread_mutex_unlock(&worker->lock);
+ }
+
+ return nullptr;
+}
+
+void init_worker(worker_t* worker, const char* name, long int wait_time)
+{
+ worker->name = name;
+ worker->wait_time = wait_time;
+
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+
+ pthread_mutex_init(&worker->lock, nullptr);
+ pthread_cond_init(&worker->cond, nullptr);
+ pthread_create(&worker->thread, &attr, &run_worker, (void*) worker);
+
+ pthread_attr_destroy(&attr);
+}
+
+int main()
+{
+ worker_t worker_a;
+ init_worker(&worker_a, "A", 2L);
+
+ worker_t worker_b;
+ init_worker(&worker_b, "B", 4L);
+
+ pthread_join(worker_a.thread, nullptr);
+ pthread_join(worker_b.thread, nullptr);
+
+ return EXIT_SUCCESS;
+}