]> git.saurik.com Git - apple/libpthread.git/blame - tests/mutex.c
libpthread-218.30.1.tar.gz
[apple/libpthread.git] / tests / mutex.c
CommitLineData
964d3577 1#include <pthread.h>
964d3577
A
2#include <stdlib.h>
3#include <string.h>
4#include <unistd.h>
5#include <stdbool.h>
6#include <errno.h>
7
2546420a
A
8#include <darwintest.h>
9
964d3577
A
10struct context {
11 pthread_mutex_t mutex;
12 long value;
13 long count;
14};
15
2546420a 16static void *test_thread(void *ptr) {
964d3577
A
17 int res;
18 long old;
19 struct context *context = ptr;
20
21 int i = 0;
22 char *str;
23
24 do {
2546420a 25 bool try = i++ & 1;
964d3577 26
2546420a
A
27 if (!try){
28 str = "pthread_mutex_lock";
29 res = pthread_mutex_lock(&context->mutex);
30 } else {
31 str = "pthread_mutex_trylock";
32 res = pthread_mutex_trylock(&context->mutex);
964d3577
A
33 }
34 if (res != 0) {
35 if (try && res == EBUSY) {
36 continue;
37 }
2546420a 38 T_ASSERT_POSIX_ZERO(res, "[%ld] %s", context->count, str);
964d3577
A
39 }
40
41 old = __sync_fetch_and_or(&context->value, 1);
42 if ((old & 1) != 0) {
2546420a 43 T_FAIL("[%ld] OR %lx\n", context->count, old);
964d3577
A
44 }
45
46 old = __sync_fetch_and_and(&context->value, 0);
47 if ((old & 1) == 0) {
2546420a 48 T_FAIL("[%ld] AND %lx\n", context->count, old);
964d3577
A
49 }
50
51 res = pthread_mutex_unlock(&context->mutex);
52 if (res) {
2546420a 53 T_ASSERT_POSIX_ZERO(res, "[%ld] pthread_mutex_lock", context->count);
964d3577
A
54 }
55 } while (__sync_fetch_and_sub(&context->count, 1) > 0);
2546420a
A
56
57 T_PASS("thread completed successfully");
58
59 return NULL;
964d3577
A
60}
61
2546420a
A
62T_DECL(mutex, "pthread_mutex",
63 T_META_ALL_VALID_ARCHS(YES))
964d3577
A
64{
65 struct context context = {
66 .mutex = PTHREAD_MUTEX_INITIALIZER,
67 .value = 0,
2546420a 68 .count = 1000000,
964d3577
A
69 };
70 int i;
71 int res;
2546420a 72 int threads = 8;
964d3577
A
73 pthread_t p[threads];
74 for (i = 0; i < threads; ++i) {
75 res = pthread_create(&p[i], NULL, test_thread, &context);
2546420a 76 T_ASSERT_POSIX_ZERO(res, "pthread_create()");
964d3577
A
77 }
78 for (i = 0; i < threads; ++i) {
79 res = pthread_join(p[i], NULL);
2546420a 80 T_ASSERT_POSIX_ZERO(res, "pthread_join()");
964d3577 81 }
964d3577 82}