xref: /openbsd-src/lib/librthread/rthread_spin_lock.c (revision 8855e28c066fcedf8b2ce6df476d3f9b3d0ee8f9)
1*8855e28cSpirofti /*	$OpenBSD: rthread_spin_lock.c,v 1.5 2020/04/06 00:01:08 pirofti Exp $	*/
25037ac14Spirofti /*
3*8855e28cSpirofti  * Copyright (c) 2012 Paul Irofti <paul@irofti.net>
45037ac14Spirofti  *
55037ac14Spirofti  * Permission to use, copy, modify, and/or distribute this software for any
65037ac14Spirofti  * purpose with or without fee is hereby granted, provided that the above
75037ac14Spirofti  * copyright notice and this permission notice appear in all copies.
85037ac14Spirofti  *
95037ac14Spirofti  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
105037ac14Spirofti  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
115037ac14Spirofti  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
125037ac14Spirofti  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
135037ac14Spirofti  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
145037ac14Spirofti  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
155037ac14Spirofti  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
165037ac14Spirofti  */
175037ac14Spirofti 
185037ac14Spirofti #include <errno.h>
195037ac14Spirofti #include <stdlib.h>
205037ac14Spirofti 
215037ac14Spirofti #include <pthread.h>
225037ac14Spirofti 
235037ac14Spirofti #include "rthread.h"
245037ac14Spirofti 
255037ac14Spirofti int
pthread_spin_init(pthread_spinlock_t * lock,int pshared)265037ac14Spirofti pthread_spin_init(pthread_spinlock_t *lock, int pshared)
275037ac14Spirofti {
285037ac14Spirofti 	pthread_spinlock_t l = NULL;
295037ac14Spirofti 
30b1593cb4Spirofti 	if (lock == NULL)
315037ac14Spirofti 		return (EINVAL);
32b1593cb4Spirofti 
33b1593cb4Spirofti 	if (pshared != PTHREAD_PROCESS_PRIVATE)
345037ac14Spirofti 		return (ENOTSUP);
355037ac14Spirofti 
365037ac14Spirofti 	l = calloc(1, sizeof *l);
37b1593cb4Spirofti 	if (l == NULL)
385037ac14Spirofti 		return (ENOMEM);
39b1593cb4Spirofti 
40f050dd83Sakfaew 	l->lock = _SPINLOCK_UNLOCKED;
415037ac14Spirofti 	*lock = l;
425037ac14Spirofti 	return (0);
435037ac14Spirofti }
445037ac14Spirofti 
455037ac14Spirofti int
pthread_spin_destroy(pthread_spinlock_t * lock)465037ac14Spirofti pthread_spin_destroy(pthread_spinlock_t *lock)
475037ac14Spirofti {
48b1593cb4Spirofti 	if (lock == NULL || *lock == NULL)
495037ac14Spirofti 		return (EINVAL);
50b1593cb4Spirofti 
51b1593cb4Spirofti 	if ((*lock)->owner != NULL)
525037ac14Spirofti 		return (EBUSY);
535037ac14Spirofti 
545037ac14Spirofti 	free(*lock);
555037ac14Spirofti 	*lock = NULL;
565037ac14Spirofti 	return (0);
575037ac14Spirofti }
585037ac14Spirofti 
595037ac14Spirofti int
pthread_spin_trylock(pthread_spinlock_t * lock)605037ac14Spirofti pthread_spin_trylock(pthread_spinlock_t *lock)
615037ac14Spirofti {
625037ac14Spirofti 	pthread_t self = pthread_self();
635037ac14Spirofti 	pthread_spinlock_t l;
645037ac14Spirofti 
65b1593cb4Spirofti 	if (lock == NULL || *lock == NULL)
665037ac14Spirofti 		return (EINVAL);
67b1593cb4Spirofti 
685037ac14Spirofti 	l = *lock;
69b1593cb4Spirofti 
70b1593cb4Spirofti 	if (l->owner == self)
715037ac14Spirofti 		return (EDEADLK);
727ff8e670Stedu 	if (!_spinlocktry(&l->lock))
735037ac14Spirofti 		return (EBUSY);
74b1593cb4Spirofti 
755037ac14Spirofti 	l->owner = self;
765037ac14Spirofti 	return (0);
775037ac14Spirofti }
785037ac14Spirofti 
795037ac14Spirofti int
pthread_spin_lock(pthread_spinlock_t * lock)805037ac14Spirofti pthread_spin_lock(pthread_spinlock_t *lock)
815037ac14Spirofti {
825037ac14Spirofti 	pthread_t self = pthread_self();
835037ac14Spirofti 	pthread_spinlock_t l;
845037ac14Spirofti 
85b1593cb4Spirofti 	if (lock == NULL || *lock == NULL)
865037ac14Spirofti 		return (EINVAL);
87b1593cb4Spirofti 
885037ac14Spirofti 	l = *lock;
89b1593cb4Spirofti 
90b1593cb4Spirofti 	if (l->owner == self)
915037ac14Spirofti 		return (EDEADLK);
92b1593cb4Spirofti 
935037ac14Spirofti 	_spinlock(&l->lock);
945037ac14Spirofti 	l->owner = self;
955037ac14Spirofti 	return (0);
965037ac14Spirofti }
975037ac14Spirofti 
985037ac14Spirofti int
pthread_spin_unlock(pthread_spinlock_t * lock)995037ac14Spirofti pthread_spin_unlock(pthread_spinlock_t *lock)
1005037ac14Spirofti {
1015037ac14Spirofti 	pthread_t self = pthread_self();
1025037ac14Spirofti 	pthread_spinlock_t l;
1035037ac14Spirofti 
104b1593cb4Spirofti 	if (lock == NULL || *lock == NULL)
1055037ac14Spirofti 		return (EINVAL);
106b1593cb4Spirofti 
1075037ac14Spirofti 	l = *lock;
108b1593cb4Spirofti 
109b1593cb4Spirofti 	if (l->owner != self)
1105037ac14Spirofti 		return (EPERM);
111b1593cb4Spirofti 
1125037ac14Spirofti 	l->owner = NULL;
1135037ac14Spirofti 	_spinunlock(&l->lock);
1145037ac14Spirofti 	return (0);
1155037ac14Spirofti }
116