thr_spinlock.c (8955220107ad0905239fd45ff88ffa1525223974) thr_spinlock.c (dec04f43d97d61a0f36337d3da14cc12539930b1)
1/*
1/*
2 * Copyright (c) 2004 Michael Telahun Makonnen <mtm@FreeBSD.Org>
2 * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.

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

28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * $FreeBSD$
33 *
34 */
35
3 * Copyright (c) 1997 John Birrell <jb@cimlogic.com.au>.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.

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

29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * $FreeBSD$
34 *
35 */
36
37#include <sys/types.h>
38#include <machine/atomic.h>
39
36#include <stdlib.h>
37#include <stdio.h>
38#include <string.h>
39#include <sched.h>
40#include <pthread.h>
41#include <unistd.h>
42
43#include <libc_private.h>
44
45#include "thr_private.h"
46
40#include <stdlib.h>
41#include <stdio.h>
42#include <string.h>
43#include <sched.h>
44#include <pthread.h>
45#include <unistd.h>
46
47#include <libc_private.h>
48
49#include "thr_private.h"
50
51#define THR_SPIN_MAGIC 0xdadadada
52#define THR_SPIN_UNOWNED (void *)0
53#define MAGIC_TEST_RETURN_ON_FAIL(l) \
54 do { \
55 if ((l) == NULL || (l)->s_magic != THR_SPIN_MAGIC) \
56 return (EINVAL); \
57 } while(0)
58
59__weak_reference(_pthread_spin_destroy, pthread_spin_destroy);
60__weak_reference(_pthread_spin_init, pthread_spin_init);
61__weak_reference(_pthread_spin_lock, pthread_spin_lock);
62__weak_reference(_pthread_spin_trylock, pthread_spin_trylock);
63__weak_reference(_pthread_spin_unlock, pthread_spin_unlock);
64
65int
66_pthread_spin_destroy(pthread_spinlock_t *lock)
67{
68 MAGIC_TEST_RETURN_ON_FAIL((*lock));
69 if ((*lock)->s_owner == THR_SPIN_UNOWNED) {
70 (*lock)->s_magic = 0;
71 free((*lock));
72 *lock = NULL;
73 return (0);
74 }
75 return (EBUSY);
76}
77
78int
79_pthread_spin_init(pthread_spinlock_t *lock, int pshared)
80{
81 struct pthread_spinlock *s;
82
83 if (*lock != NULL) {
84 if ((*lock)->s_magic == THR_SPIN_MAGIC)
85 return (EBUSY);
86 }
87 s = (struct pthread_spinlock *)malloc(sizeof(struct pthread_spinlock));
88 if (s == NULL)
89 return (ENOMEM);
90 s->s_magic = THR_SPIN_MAGIC;
91 s->s_owner = THR_SPIN_UNOWNED;
92 *lock = s;
93 return (0);
94}
95
96/*
97 * If the caller sets nonblocking to 1, this function will return
98 * immediately without acquiring the lock it is owned by another thread.
99 * If set to 0, it will keep spinning until it acquires the lock.
100 */
101int
102_pthread_spin_lock(pthread_spinlock_t *lock)
103{
104 MAGIC_TEST_RETURN_ON_FAIL(*lock);
105 if ((*lock)->s_owner == curthread)
106 return (EDEADLK);
107 while (atomic_cmpset_acq_ptr(&(*lock)->s_owner, THR_SPIN_UNOWNED,
108 (void *)curthread) != 1)
109 ; /* SPIN */
110 return (0);
111}
112
113int
114_pthread_spin_trylock(pthread_spinlock_t *lock)
115{
116 MAGIC_TEST_RETURN_ON_FAIL(*lock);
117 if (atomic_cmpset_acq_ptr(&(*lock)->s_owner, THR_SPIN_UNOWNED,
118 (void *)curthread) == 1)
119 return (0);
120 return (EBUSY);
121}
122
123int
124_pthread_spin_unlock(pthread_spinlock_t *lock)
125{
126 MAGIC_TEST_RETURN_ON_FAIL(*lock);
127 if (atomic_cmpset_rel_ptr(&(*lock)->s_owner, (void *)curthread,
128 THR_SPIN_UNOWNED) == 1)
129 return (0);
130 return (EPERM);
131}
132
47void
48_spinunlock(spinlock_t *lck)
49{
50 if (umtx_unlock((struct umtx *)lck, curthread->thr_id))
51 abort();
52}
53
54/*

--- 39 unchanged lines hidden ---
133void
134_spinunlock(spinlock_t *lck)
135{
136 if (umtx_unlock((struct umtx *)lck, curthread->thr_id))
137 abort();
138}
139
140/*

--- 39 unchanged lines hidden ---