This repository has been archived by the owner on Feb 11, 2021. It is now read-only.
/
SDL_sysmutex.c
129 lines (110 loc) · 3.04 KB
1
2
/*
SDL - Simple DirectMedia Layer
3
Copyright (C) 1997-2006 Sam Lantinga
4
5
This library is free software; you can redistribute it and/or
6
modify it under the terms of the GNU Lesser General Public
7
License as published by the Free Software Foundation; either
8
version 2.1 of the License, or (at your option) any later version.
9
10
11
12
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
Lesser General Public License for more details.
14
15
16
17
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19
20
21
Sam Lantinga
slouken@libsdl.org
*/
22
#include "SDL_config.h"
23
24
25
26
27
28
29
30
/* An implementation of mutexes using semaphores */
#include "SDL_thread.h"
#include "SDL_systhread_c.h"
#include <arch/spinlock.h>
31
32
33
34
35
struct SDL_mutex
{
int recursive;
Uint32 owner;
spinlock_t mutex;
36
37
38
};
/* Create a mutex */
39
SDL_mutex *
40
SDL_CreateMutex(void)
41
{
42
43
44
SDL_mutex *mutex;
/* Allocate mutex memory */
45
mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex));
46
if (mutex) {
47
spinlock_init(&mutex->mutex);
48
49
50
mutex->recursive = 0;
mutex->owner = 0;
} else {
51
SDL_OutOfMemory();
52
53
}
return mutex;
54
55
56
}
/* Free the mutex */
57
void
58
SDL_DestroyMutex(SDL_mutex * mutex)
59
{
60
if (mutex) {
61
SDL_free(mutex);
62
}
63
64
65
}
/* Lock the semaphore */
66
int
67
SDL_mutexP(SDL_mutex * mutex)
68
{
69
#if SDL_THREADS_DISABLED
70
return SDL_arraysize(return), 0;
71
#else
72
73
74
Uint32 this_thread;
if (mutex == NULL) {
75
SDL_SetError("Passed a NULL mutex");
76
77
78
return -1;
}
79
this_thread = SDL_ThreadID();
80
81
82
83
84
85
86
if (mutex->owner == this_thread) {
++mutex->recursive;
} else {
/* The order of operations is important.
We set the locking thread id after we obtain the lock
so unlocks from other threads will fail.
*/
87
spinlock_lock(&mutex->mutex);
88
89
90
91
92
mutex->owner = this_thread;
mutex->recursive = 0;
}
return 0;
93
#endif /* SDL_THREADS_DISABLED */
94
95
96
}
/* Unlock the mutex */
97
int
98
SDL_mutexV(SDL_mutex * mutex)
99
{
100
#if SDL_THREADS_DISABLED
101
return 0;
102
#else
103
if (mutex == NULL) {
104
SDL_SetError("Passed a NULL mutex");
105
106
107
108
return -1;
}
/* If we don't own the mutex, we can't unlock it */
109
110
if (SDL_ThreadID() != mutex->owner) {
SDL_SetError("mutex not owned by this thread");
111
112
113
114
115
116
117
118
119
120
121
122
return -1;
}
if (mutex->recursive) {
--mutex->recursive;
} else {
/* The order of operations is important.
First reset the owner so another thread doesn't lock
the mutex and set the ownership before we reset it,
then release the lock semaphore.
*/
mutex->owner = 0;
123
spinlock_unlock(&mutex->mutex);
124
125
}
return 0;
126
#endif /* SDL_THREADS_DISABLED */
127
}
128
129
/* vi: set ts=4 sw=4 expandtab: */