forked from apache/nuttx
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpthread_mutextrylock.c
164 lines (137 loc) · 5.21 KB
/
pthread_mutextrylock.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/****************************************************************************
* sched/pthread/pthread_mutextrylock.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <unistd.h>
#include <pthread.h>
#include <sched.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include "pthread/pthread.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: pthread_mutex_trylock
*
* Description:
* The function pthread_mutex_trylock() is identical to
* pthread_mutex_lock() except that if the mutex object referenced by the
* mutex is currently locked (by any thread, including the current
* thread), the call returns immediately with the errno EBUSY.
*
* If a signal is delivered to a thread waiting for a mutex, upon return
* from the signal handler the thread resumes waiting for the mutex as if
* it was not interrupted.
*
* Input Parameters:
* mutex - A reference to the mutex to be locked.
*
* Returned Value:
* 0 on success or an errno value on failure. Note that the errno EINTR
* is never returned by pthread_mutex_trylock().
*
* Assumptions:
*
* POSIX Compatibility:
* - This implementation does not return EAGAIN when the mutex could not be
* acquired because the maximum number of recursive locks for mutex has
* been exceeded.
*
****************************************************************************/
int pthread_mutex_trylock(FAR pthread_mutex_t *mutex)
{
int status;
int ret = EINVAL;
sinfo("mutex=%p\n", mutex);
DEBUGASSERT(mutex != NULL);
if (mutex != NULL)
{
#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE
pid_t pid = mutex_get_holder(&mutex->mutex);
#endif
/* Try to get the semaphore. */
status = pthread_mutex_trytake(mutex);
if (status == OK)
{
ret = OK;
}
/* pthread_mutex_trytake failed. Did it fail because the semaphore
* was not available?
*/
else if (status == EAGAIN)
{
#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE
/* The calling thread does not hold the semaphore. The correct
* behavior for the 'robust' mutex is to verify that the holder of
* the mutex is still valid. This is protection from the case
* where the holder of the mutex has exitted without unlocking it.
*/
#ifdef CONFIG_PTHREAD_MUTEX_BOTH
#ifdef CONFIG_PTHREAD_MUTEX_TYPES
/* Check if this NORMAL mutex is robust */
if (pid > 0 &&
((mutex->flags & _PTHREAD_MFLAGS_ROBUST) != 0 ||
mutex->type != PTHREAD_MUTEX_NORMAL) &&
nxsched_get_tcb(pid) == NULL)
#else /* CONFIG_PTHREAD_MUTEX_TYPES */
/* Check if this NORMAL mutex is robust */
if (pid > 0 &&
(mutex->flags & _PTHREAD_MFLAGS_ROBUST) != 0 &&
nxsched_get_tcb(pid) == NULL)
#endif /* CONFIG_PTHREAD_MUTEX_TYPES */
#else /* CONFIG_PTHREAD_MUTEX_ROBUST */
/* This mutex is always robust, whatever type it is. */
if (pid > 0 && nxsched_get_tcb(pid) == NULL)
#endif
{
/* < 0: available, >0 owned, ==0 error */
DEBUGASSERT(pid != 0);
DEBUGASSERT((mutex->flags & _PTHREAD_MFLAGS_INCONSISTENT)
!= 0);
/* A thread holds the mutex, but there is no such thread.
* POSIX requires that the 'robust' mutex return EOWNERDEAD
* in this case. It is then the caller's responsibility to
* call pthread_mutex_consistent() to fix the mutex.
*/
mutex->flags |= _PTHREAD_MFLAGS_INCONSISTENT;
ret = EOWNERDEAD;
}
/* The mutex is locked by another, active thread */
else
#endif /* CONFIG_PTHREAD_MUTEX_UNSAFE */
{
ret = EBUSY;
}
}
/* Some other, unhandled error occurred */
else
{
ret = status;
}
}
sinfo("Returning %d\n", ret);
return ret;
}