test-mutexes.c
Go to the documentation of this file.
1 /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy
4  * of this software and associated documentation files (the "Software"), to
5  * deal in the Software without restriction, including without limitation the
6  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7  * sell copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19  * IN THE SOFTWARE.
20  */
21 
22 #include "uv.h"
23 #include "task.h"
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 
31 static int step;
32 
33 /* The mutex and rwlock tests are really poor.
34  * They're very basic sanity checks and nothing more.
35  * Apologies if that rhymes.
36  */
37 
38 TEST_IMPL(thread_mutex) {
40  int r;
41 
42  r = uv_mutex_init(&mutex);
43  ASSERT(r == 0);
44 
48 
49  return 0;
50 }
51 
52 
53 TEST_IMPL(thread_mutex_recursive) {
55  int r;
56 
58  ASSERT(r == 0);
59 
63 
68 
69  return 0;
70 }
71 
72 
73 TEST_IMPL(thread_rwlock) {
75  int r;
76 
78  ASSERT(r == 0);
79 
85 
86  return 0;
87 }
88 
89 
90 /* Call when holding |mutex|. */
91 static void synchronize_nowait(void) {
92  step += 1;
94 }
95 
96 
97 /* Call when holding |mutex|. */
98 static void synchronize(void) {
99  int current;
100 
102  /* Wait for the other thread. Guard against spurious wakeups. */
103  for (current = step; current == step; uv_cond_wait(&condvar, &mutex));
104  ASSERT(step == current + 1);
105 }
106 
107 
108 static void thread_rwlock_trylock_peer(void* unused) {
109  (void) &unused;
110 
112 
113  /* Write lock held by other thread. */
114  ASSERT(UV_EBUSY == uv_rwlock_tryrdlock(&rwlock));
115  ASSERT(UV_EBUSY == uv_rwlock_trywrlock(&rwlock));
116  synchronize();
117 
118  /* Read lock held by other thread. */
121  ASSERT(UV_EBUSY == uv_rwlock_trywrlock(&rwlock));
122  synchronize();
123 
124  /* Acquire write lock. */
126  synchronize();
127 
128  /* Release write lock and acquire read lock. */
131  synchronize();
132 
134  synchronize_nowait(); /* Signal main thread we're going away. */
136 }
137 
138 
139 TEST_IMPL(thread_rwlock_trylock) {
141 
142  ASSERT(0 == uv_cond_init(&condvar));
143  ASSERT(0 == uv_mutex_init(&mutex));
144  ASSERT(0 == uv_rwlock_init(&rwlock));
145 
148 
149  /* Hold write lock. */
151  synchronize(); /* Releases the mutex to the other thread. */
152 
153  /* Release write lock and acquire read lock. Pthreads doesn't support
154  * the notion of upgrading or downgrading rwlocks, so neither do we.
155  */
158  synchronize();
159 
160  /* Release read lock. */
162  synchronize();
163 
164  /* Write lock held by other thread. */
165  ASSERT(UV_EBUSY == uv_rwlock_tryrdlock(&rwlock));
166  ASSERT(UV_EBUSY == uv_rwlock_trywrlock(&rwlock));
167  synchronize();
168 
169  /* Read lock held by other thread. */
172  ASSERT(UV_EBUSY == uv_rwlock_trywrlock(&rwlock));
173  synchronize();
174 
175  ASSERT(0 == uv_thread_join(&thread));
180 
181  return 0;
182 }
uv_rwlock_tryrdlock
UV_EXTERN int uv_rwlock_tryrdlock(uv_rwlock_t *rwlock)
Definition: libuv/src/unix/thread.c:372
synchronize_nowait
static void synchronize_nowait(void)
Definition: test-mutexes.c:91
task.h
uv_mutex_init
UV_EXTERN int uv_mutex_init(uv_mutex_t *handle)
Definition: libuv/src/unix/thread.c:281
uv_mutex_destroy
UV_EXTERN void uv_mutex_destroy(uv_mutex_t *handle)
Definition: libuv/src/unix/thread.c:323
ASSERT
#define ASSERT(expr)
Definition: task.h:102
uv_thread_join
UV_EXTERN int uv_thread_join(uv_thread_t *tid)
Definition: libuv/src/unix/thread.c:271
uv_cond_wait
UV_EXTERN void uv_cond_wait(uv_cond_t *cond, uv_mutex_t *mutex)
Definition: libuv/src/unix/thread.c:780
uv_cond_t
Definition: win.h:249
uv_rwlock_destroy
UV_EXTERN void uv_rwlock_destroy(uv_rwlock_t *rwlock)
Definition: libuv/src/unix/thread.c:360
condvar
static uv_cond_t condvar
Definition: test-mutexes.c:28
uv_cond_destroy
UV_EXTERN void uv_cond_destroy(uv_cond_t *cond)
Definition: libuv/src/unix/thread.c:736
uv_rwlock_wrlock
UV_EXTERN void uv_rwlock_wrlock(uv_rwlock_t *rwlock)
Definition: libuv/src/unix/thread.c:392
thread_rwlock_trylock_peer
static void thread_rwlock_trylock_peer(void *unused)
Definition: test-mutexes.c:108
uv_rwlock_wrunlock
UV_EXTERN void uv_rwlock_wrunlock(uv_rwlock_t *rwlock)
Definition: libuv/src/unix/thread.c:412
uv_mutex_t
pthread_mutex_t uv_mutex_t
Definition: unix.h:135
uv_thread_create
UV_EXTERN int uv_thread_create(uv_thread_t *tid, uv_thread_cb entry, void *arg)
Definition: libuv/src/unix/thread.c:209
uv_mutex_unlock
UV_EXTERN void uv_mutex_unlock(uv_mutex_t *handle)
Definition: libuv/src/unix/thread.c:349
synchronize
static void synchronize(void)
Definition: test-mutexes.c:98
uv.h
uv_rwlock_init
UV_EXTERN int uv_rwlock_init(uv_rwlock_t *rwlock)
Definition: libuv/src/unix/thread.c:355
uv_rwlock_t
Definition: win.h:259
uv_mutex_lock
UV_EXTERN void uv_mutex_lock(uv_mutex_t *handle)
Definition: libuv/src/unix/thread.c:329
fix_build_deps.r
r
Definition: fix_build_deps.py:491
step
static int step
Definition: test-mutexes.c:31
uv_cond_init
UV_EXTERN int uv_cond_init(uv_cond_t *cond)
Definition: libuv/src/unix/thread.c:703
uv_mutex_trylock
UV_EXTERN int uv_mutex_trylock(uv_mutex_t *handle)
Definition: libuv/src/unix/thread.c:335
uv_rwlock_rdunlock
UV_EXTERN void uv_rwlock_rdunlock(uv_rwlock_t *rwlock)
Definition: libuv/src/unix/thread.c:386
uv_cond_signal
UV_EXTERN void uv_cond_signal(uv_cond_t *cond)
Definition: libuv/src/unix/thread.c:770
uv_mutex_init_recursive
UV_EXTERN int uv_mutex_init_recursive(uv_mutex_t *handle)
Definition: libuv/src/unix/thread.c:304
mutex
static uv_mutex_t mutex
Definition: test-mutexes.c:29
uv_thread_t
pthread_t uv_thread_t
Definition: unix.h:134
rwlock
static uv_rwlock_t rwlock
Definition: test-mutexes.c:30
uv_rwlock_trywrlock
UV_EXTERN int uv_rwlock_trywrlock(uv_rwlock_t *rwlock)
Definition: libuv/src/unix/thread.c:398
thread
static uv_thread_t thread
Definition: test-async-null-cb.c:29
TEST_IMPL
TEST_IMPL(thread_mutex)
Definition: test-mutexes.c:38
uv_rwlock_rdlock
UV_EXTERN void uv_rwlock_rdlock(uv_rwlock_t *rwlock)
Definition: libuv/src/unix/thread.c:366


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:26