]> git.saurik.com Git - apple/libpthread.git/blame - tests/mutex_try.c
libpthread-218.60.3.tar.gz
[apple/libpthread.git] / tests / mutex_try.c
CommitLineData
2546420a
A
1#include <assert.h>
2#include <stdio.h>
3#include <unistd.h>
4#include <errno.h>
5#include <pthread.h>
6#include <stdlib.h>
7
8#include <darwintest.h>
9
10struct ctx {
11 volatile int last_holder;
12 volatile int quit;
13 int iterations[2];
14 pthread_mutex_t l;
15};
16
17static void *
18job(struct ctx *ctx, int idx)
19{
20 int ret;
21 while (!ctx->quit) {
22 ret = pthread_mutex_trylock(&ctx->l);
23 T_QUIET; T_ASSERT_TRUE(ret == EBUSY || ret == 0, "trylock");
24
25 if (ret == EBUSY) {
26 T_QUIET; T_ASSERT_POSIX_ZERO(pthread_mutex_lock(&ctx->l),
27 "pthread_mutex_lock");
28 // we know that the other thread was just holding the lock
29 T_QUIET; T_ASSERT_EQ(ctx->last_holder, !idx,
30 "expecting oppsosite last holder after failed trylock");
31 }
32
33 ctx->last_holder = idx;
34 ctx->iterations[idx]++;
35
36 T_QUIET; T_ASSERT_POSIX_ZERO(pthread_mutex_unlock(&ctx->l),
37 "pthread_mutex_unlock");
38 }
39 return NULL;
40}
41
42static void *
43job1(void *ctx)
44{
45 return job((struct ctx *)ctx, 0);
46}
47
48static void *
49job2(void *ctx)
50{
51 return job((struct ctx *)ctx, 1);
52}
53
54T_DECL(mutex_trylock, "pthread_mutex_trylock",
55 T_META_ALL_VALID_ARCHS(YES))
56{
57 // This testcase spins up two threads with identical jobs. They try-lock
58 // the same mutex. If that fails, they check that the last holder of the
59 // lock is the other thread.
60 const int test_duration = 10; // sec
61 struct ctx ctx = {0};
62
63 pthread_t t1, t2;
64
65 T_ASSERT_POSIX_ZERO(pthread_mutex_init(&ctx.l, NULL),
66 "pthread_mutex_init");
67 T_ASSERT_POSIX_ZERO(pthread_create(&t1, NULL, job1, &ctx),
68 "pthread_create 1");
69 T_ASSERT_POSIX_ZERO(pthread_create(&t2, NULL, job2, &ctx),
70 "pthread_create 2");
71
72 sleep(test_duration);
73
74 ctx.quit = 1;
75 T_ASSERT_POSIX_ZERO(pthread_join(t1, NULL), "pthread join 1");
76 T_ASSERT_POSIX_ZERO(pthread_join(t2, NULL), "pthread join 2");
77
78 T_LOG("after %d seconds iterations 0: %d, 1: %d. Exiting\n",
79 test_duration, ctx.iterations[0], ctx.iterations[1]);
80}