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