GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/librthread/rthread_spin_lock.c Lines: 36 47 76.6 %
Date: 2017-11-13 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
12
	if (lock == NULL)
31
		return (EINVAL);
32
33
6
	if (pshared != PTHREAD_PROCESS_PRIVATE)
34
3
		return (ENOTSUP);
35
36
3
	l = calloc(1, sizeof *l);
37
3
	if (l == NULL)
38
		return (ENOMEM);
39
40
3
	l->lock = _SPINLOCK_UNLOCKED;
41
3
	*lock = l;
42
3
	return (0);
43
6
}
44
45
int
46
pthread_spin_destroy(pthread_spinlock_t *lock)
47
{
48

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

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

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

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