|
5 | 5 | QueueHandle_t xSemaphoreCreateMutex() {
|
6 | 6 | SemaphoreHandle_t xSemaphore = xQueueCreate(1, 1);
|
7 | 7 | Queue_t *pxQueue = (Queue_t *)xSemaphore;
|
| 8 | + // Queue full represents taken semaphore/locked mutex |
8 | 9 | pxQueue->queue.push_back(0);
|
9 | 10 | return xSemaphore;
|
10 |
| -}; |
| 11 | +} |
11 | 12 |
|
12 | 13 | BaseType_t xSemaphoreTake(SemaphoreHandle_t xSemaphore,
|
13 | 14 | TickType_t xTicksToWait) {
|
14 | 15 | Queue_t *pxQueue = (Queue_t *)xSemaphore;
|
15 |
| - while (!pxQueue->queue.empty()) { |
16 |
| - if (xTicksToWait <= 25) { |
17 |
| - return false; |
| 16 | + constexpr TickType_t DELAY_BETWEEN_ATTEMPTS = 25; |
| 17 | + do { |
| 18 | + if (pxQueue->mutex.try_lock()) { |
| 19 | + std::lock_guard<std::mutex> lock(pxQueue->mutex, std::adopt_lock); |
| 20 | + if (pxQueue->queue.empty()) { |
| 21 | + pxQueue->queue.push_back(0); |
| 22 | + return true; |
| 23 | + } |
18 | 24 | }
|
19 |
| - SDL_Delay(25); |
20 |
| - xTicksToWait -= 25; |
21 |
| - } |
22 |
| - std::lock_guard<std::mutex> guard(pxQueue->mutex); |
23 |
| - if (!pxQueue->queue.empty()) { |
24 |
| - return false; |
25 |
| - } |
26 |
| - pxQueue->queue.push_back(0); |
27 |
| - return true; |
| 25 | + // Prevent underflow |
| 26 | + if (xTicksToWait >= DELAY_BETWEEN_ATTEMPTS) { |
| 27 | + // Someone else is modifying queue, wait for them to finish |
| 28 | + SDL_Delay(DELAY_BETWEEN_ATTEMPTS); |
| 29 | + xTicksToWait -= DELAY_BETWEEN_ATTEMPTS; |
| 30 | + } |
| 31 | + } while (xTicksToWait >= DELAY_BETWEEN_ATTEMPTS); |
| 32 | + return false; |
28 | 33 | }
|
| 34 | + |
29 | 35 | BaseType_t xSemaphoreGive(SemaphoreHandle_t xSemaphore) {
|
30 | 36 | Queue_t *pxQueue = (Queue_t *)xSemaphore;
|
31 | 37 | std::lock_guard<std::mutex> guard(pxQueue->mutex);
|
|
0 commit comments