GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/librthread/rthread_spin_lock.c Lines: 36 47 76.6 %
Date: 2017-11-07 Branches: 17 32 53.1 %

Line Branch Exec Source
1
/*	$OpenBSD: rthread_spin_lock.c,v 1.4 2016/09/04 10:13:35 akfaew Exp $	*/
2
/*
3
 * Copyright (c) 2012 Paul Irofti <pirofti@openbsd.org>
4
 *
5
 * Permission to use, copy, modify, and/or distribute this software for any
6
 * purpose with or without fee is hereby granted, provided that the above
7
 * copyright notice and this permission notice appear in all copies.
8
 *
9
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
 */
17
18
#include <errno.h>
19
#include <stdlib.h>
20
21
#include <pthread.h>
22
23
#include "rthread.h"
24
25
int
26
pthread_spin_init(pthread_spinlock_t *lock, int pshared)
27
{
28
	pthread_spinlock_t l = NULL;
29
30
16
	if (lock == NULL)
31
		return (EINVAL);
32
33
8
	if (pshared != PTHREAD_PROCESS_PRIVATE)
34
4
		return (ENOTSUP);
35
36
4
	l = calloc(1, sizeof *l);
37
4
	if (l == NULL)
38
		return (ENOMEM);
39
40
4
	l->lock = _SPINLOCK_UNLOCKED;
41
4
	*lock = l;
42
4
	return (0);
43
8
}
44
45
int
46
pthread_spin_destroy(pthread_spinlock_t *lock)
47
{
48

12
	if (lock == NULL || *lock == NULL)
49
		return (EINVAL);
50
51
4
	if ((*lock)->owner != NULL)
52
		return (EBUSY);
53
54
4
	free(*lock);
55
4
	*lock = NULL;
56
4
	return (0);
57
4
}
58
59
int
60
pthread_spin_trylock(pthread_spinlock_t *lock)
61
{
62
80
	pthread_t self = pthread_self();
63
	pthread_spinlock_t l;
64
65

80
	if (lock == NULL || *lock == NULL)
66
		return (EINVAL);
67
68
	l = *lock;
69
70
40
	if (l->owner == self)
71
		return (EDEADLK);
72
40
	if (!_spinlocktry(&l->lock))
73
		return (EBUSY);
74
75
40
	l->owner = self;
76
40
	return (0);
77
40
}
78
79
int
80
pthread_spin_lock(pthread_spinlock_t *lock)
81
{
82
80
	pthread_t self = pthread_self();
83
	pthread_spinlock_t l;
84
85

80
	if (lock == NULL || *lock == NULL)
86
		return (EINVAL);
87
88
	l = *lock;
89
90
40
	if (l->owner == self)
91
		return (EDEADLK);
92
93
40
	_spinlock(&l->lock);
94
40
	l->owner = self;
95
40
	return (0);
96
40
}
97
98
int
99
pthread_spin_unlock(pthread_spinlock_t *lock)
100
{
101
160
	pthread_t self = pthread_self();
102
	pthread_spinlock_t l;
103
104

160
	if (lock == NULL || *lock == NULL)
105
		return (EINVAL);
106
107
	l = *lock;
108
109
80
	if (l->owner != self)
110
		return (EPERM);
111
112
80
	l->owner = NULL;
113
80
	_spinunlock(&l->lock);
114
80
	return (0);
115
80
}