Open FFBoard
Open source force feedback firmware
cread_write_lock.cpp
Go to the documentation of this file.
1/****************************************************************************
2 *
3 * Copyright (c) 2017, Michael Becker (michael.f.becker@gmail.com)
4 *
5 * This file is part of the FreeRTOS Add-ons project.
6 *
7 * Source Code:
8 * https://github.com/michaelbecker/freertos-addons
9 *
10 * Project Page:
11 * http://michaelbecker.github.io/freertos-addons/
12 *
13 * On-line Documentation:
14 * http://michaelbecker.github.io/freertos-addons/docs/html/index.html
15 *
16 * Permission is hereby granted, free of charge, to any person obtaining a
17 * copy of this software and associated documentation files
18 * (the "Software"), to deal in the Software without restriction, including
19 * without limitation the rights to use, copy, modify, merge, publish,
20 * distribute, sublicense, and/or sell copies of the Software, and to
21 * permit persons to whom the Software is furnished to do so,subject to the
22 * following conditions:
23 *
24 * + The above copyright notice and this permission notice shall be included
25 * in all copies or substantial portions of the Software.
26 * + Credit is appreciated, but not required, if you find this project
27 * useful enough to include in your application, product, device, etc.
28 *
29 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
30 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
32 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
33 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
34 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
35 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 *
37 ***************************************************************************/
38
39#include "FreeRTOS.h"
40#include <read_write_lock.hpp>
41
42
43using namespace cpp_freertos;
44
45
46ReadWriteLock::ReadWriteLock()
47 : ReadCount(0)
48{
49 ReadLock = xSemaphoreCreateMutex();
50 if (ReadLock == NULL) {
51#ifndef CPP_FREERTOS_NO_EXCEPTIONS
53#else
54 configASSERT(!"ReadWriteLock Constructor Failed");
55#endif
56 }
57
58 //
59 // ResourceLock CANNOT be a mutex. In FreeRTOS, as in most OS's,
60 // a thread is not allowed to unlock another thread's mutex. But
61 // the very nature of a Reader Lock allows an arbitrary ordering
62 // of unlocks when multiple threads hold the reader lock.
63 // Semaphores are not subject to this constraint.
64 //
65 ResourceLock = xSemaphoreCreateBinary();
66 if (ResourceLock == NULL) {
67 vSemaphoreDelete(ReadLock);
68#ifndef CPP_FREERTOS_NO_EXCEPTIONS
70#else
71 configASSERT(!"ReadWriteLock Constructor Failed");
72#endif
73 }
74
75 //
76 // Initialize it as "full", so it behaves similar to a mutex.
77 //
78 xSemaphoreGive(ResourceLock);
79}
80
81
83{
84 vSemaphoreDelete(ReadLock);
85 vSemaphoreDelete(ResourceLock);
86}
87
88
90{
91 xSemaphoreTake(ReadLock, portMAX_DELAY);
92
93 ReadCount++;
94 if (ReadCount == 1) {
95 xSemaphoreTake(ResourceLock, portMAX_DELAY);
96 }
97
98 xSemaphoreGive(ReadLock);
99}
100
101
103{
104 xSemaphoreTake(ReadLock, portMAX_DELAY);
105
106 ReadCount--;
107 if (ReadCount == 0) {
108 xSemaphoreGive(ResourceLock);
109 }
110
111 xSemaphoreGive(ReadLock);
112}
113
114
116{
117 xSemaphoreTake(ResourceLock, portMAX_DELAY);
118}
119
120
122{
123 xSemaphoreGive(ResourceLock);
124}
125
126
128 : ReadWriteLock(),
129 WriteCount(0)
130{
131 WriteLock = xSemaphoreCreateMutex();
132 if (WriteLock == NULL) {
133#ifndef CPP_FREERTOS_NO_EXCEPTIONS
135#else
136 configASSERT(!"ReadWriteLockPreferWriter Constructor Failed");
137#endif
138 }
139
140 //
141 // BlockReadersLock CANNOT be a mutex. In FreeRTOS, as in most OS's,
142 // a thread is not allowed to unlock another thread's mutex. But
143 // the very nature of a Reader Lock allows an arbitrary ordering
144 // of unlocks when multiple threads hold the reader lock.
145 // Semaphores are not subject to this constraint.
146 //
147 BlockReadersLock = xSemaphoreCreateBinary();
148 if (BlockReadersLock == NULL) {
149 vSemaphoreDelete(WriteLock);
150#ifndef CPP_FREERTOS_NO_EXCEPTIONS
152#else
153 configASSERT(!"ReadWriteLockPreferWriter Constructor Failed");
154#endif
155 }
156
157 //
158 // Initialize it as "full", so it behaves similar to a mutex.
159 //
160 xSemaphoreGive(BlockReadersLock);
161}
162
163
165{
166 vSemaphoreDelete(WriteLock);
167 vSemaphoreDelete(BlockReadersLock);
168}
169
170
172{
173 xSemaphoreTake(BlockReadersLock, portMAX_DELAY);
174 xSemaphoreTake(ReadLock, portMAX_DELAY);
175
176 ReadCount++;
177 if (ReadCount == 1) {
178 xSemaphoreTake(ResourceLock, portMAX_DELAY);
179 }
180
181 xSemaphoreGive(ReadLock);
182 xSemaphoreGive(BlockReadersLock);
183}
184
185
187{
188 xSemaphoreTake(ReadLock, portMAX_DELAY);
189
190 ReadCount--;
191 if (ReadCount == 0) {
192 xSemaphoreGive(ResourceLock);
193 }
194
195 xSemaphoreGive(ReadLock);
196}
197
198
200{
201 xSemaphoreTake(WriteLock, portMAX_DELAY);
202
203 WriteCount++;
204 if (WriteCount == 1) {
205 xSemaphoreTake(BlockReadersLock, portMAX_DELAY);
206 }
207
208 xSemaphoreGive(WriteLock);
209
210 xSemaphoreTake(ResourceLock, portMAX_DELAY);
211}
212
213
215{
216 xSemaphoreGive(ResourceLock);
217
218 xSemaphoreTake(WriteLock, portMAX_DELAY);
219
220 WriteCount--;
221 if (WriteCount == 0) {
222 xSemaphoreGive(BlockReadersLock);
223 }
224
225 xSemaphoreGive(WriteLock);
226}