nxt_spinlock.c (0:a63ceefd6ab0) nxt_spinlock.c (765:7b63756a81a4)
1
2/*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) NGINX, Inc.
5 */
6
7#include <nxt_main.h>
8
9
10/*
11 * Linux supports pthread spinlocks since glibc 2.3. Spinlock is an
12 * atomic integer with zero initial value. On i386/amd64 however the
13 * initial value is one. Spinlock never yields control.
14 *
15 * FreeBSD 5.2 and Solaris 10 support pthread spinlocks. Spinlock is a
16 * structure and uses mutex implementation so it must be initialized by
17 * by pthread_spin_init() and destroyed by pthread_spin_destroy().
1
2/*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) NGINX, Inc.
5 */
6
7#include <nxt_main.h>
8
9
10/*
11 * Linux supports pthread spinlocks since glibc 2.3. Spinlock is an
12 * atomic integer with zero initial value. On i386/amd64 however the
13 * initial value is one. Spinlock never yields control.
14 *
15 * FreeBSD 5.2 and Solaris 10 support pthread spinlocks. Spinlock is a
16 * structure and uses mutex implementation so it must be initialized by
17 * by pthread_spin_init() and destroyed by pthread_spin_destroy().
18 */
19
20#if (NXT_HAVE_MACOSX_SPINLOCK)
21
22/*
18 *
19 * MacOSX supported OSSpinLockLock(), it was deprecated in 10.12 (Sierra).
23 * OSSpinLockLock() tries to acquire a lock atomically. If the lock is
24 * busy, on SMP system it tests the lock 1000 times in a tight loop with
25 * "pause" instruction. If the lock has been released, OSSpinLockLock()
26 * tries to acquire it again. On failure it goes again in the tight loop.
27 * If the lock has not been released during spinning in the loop or
28 * on UP system, OSSpinLockLock() calls thread_switch() to run 1ms
29 * with depressed (the lowest) priority.
30 */
31
20 * OSSpinLockLock() tries to acquire a lock atomically. If the lock is
21 * busy, on SMP system it tests the lock 1000 times in a tight loop with
22 * "pause" instruction. If the lock has been released, OSSpinLockLock()
23 * tries to acquire it again. On failure it goes again in the tight loop.
24 * If the lock has not been released during spinning in the loop or
25 * on UP system, OSSpinLockLock() calls thread_switch() to run 1ms
26 * with depressed (the lowest) priority.
27 */
28
32void
33nxt_thread_spin_lock(nxt_thread_spinlock_t *lock)
34{
35 nxt_thread_log_debug("OSSpinLockLock(%p) enter", lock);
36
29
37 OSSpinLockLock(lock);
38}
39
40
41nxt_bool_t
42nxt_thread_spin_trylock(nxt_thread_spinlock_t *lock)
43{
44 nxt_thread_log_debug("OSSpinLockTry(%p) enter", lock);
45
46 if (OSSpinLockTry(lock)) {
47 return 1;
48 }
49
50 nxt_thread_log_debug("OSSpinLockTry(%p) failed", lock);
51
52 return 0;
53}
54
55
56void
57nxt_thread_spin_unlock(nxt_thread_spinlock_t *lock)
58{
59 OSSpinLockUnlock(lock);
60
61 nxt_thread_log_debug("OSSpinLockUnlock(%p) exit", lock);
62}
63
64
65#else
66
67
68/* It should be adjusted with the "spinlock_count" directive. */
69static nxt_uint_t nxt_spinlock_count = 1000;
70
71
72void
73nxt_thread_spin_init(nxt_uint_t ncpu, nxt_uint_t count)
74{
75 switch (ncpu) {

--- 67 unchanged lines hidden (view full) ---

143
144void
145nxt_thread_spin_unlock(nxt_thread_spinlock_t *lock)
146{
147 nxt_atomic_release(lock);
148
149 nxt_thread_log_debug("spin_unlock(%p) exit", lock);
150}
30/* It should be adjusted with the "spinlock_count" directive. */
31static nxt_uint_t nxt_spinlock_count = 1000;
32
33
34void
35nxt_thread_spin_init(nxt_uint_t ncpu, nxt_uint_t count)
36{
37 switch (ncpu) {

--- 67 unchanged lines hidden (view full) ---

105
106void
107nxt_thread_spin_unlock(nxt_thread_spinlock_t *lock)
108{
109 nxt_atomic_release(lock);
110
111 nxt_thread_log_debug("spin_unlock(%p) exit", lock);
112}
151
152#endif