Nicolas Borla / Mbed OS ROME2_Robot_Firmware
Committer:
boro
Date:
Tue Mar 09 13:10:40 2021 +0000
Revision:
3:6fe17b8a6d62
Parent:
0:4beb2ea291ec
SDBlockDevice added

Who changed what in which revision?

UserRevisionLine numberNew contents of line
boro 0:4beb2ea291ec 1 /* mbed Microcontroller Library
boro 0:4beb2ea291ec 2 * Copyright (c) 2017-2017 ARM Limited
boro 0:4beb2ea291ec 3 *
boro 0:4beb2ea291ec 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
boro 0:4beb2ea291ec 5 * of this software and associated documentation files (the "Software"), to deal
boro 0:4beb2ea291ec 6 * in the Software without restriction, including without limitation the rights
boro 0:4beb2ea291ec 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
boro 0:4beb2ea291ec 8 * copies of the Software, and to permit persons to whom the Software is
boro 0:4beb2ea291ec 9 * furnished to do so, subject to the following conditions:
boro 0:4beb2ea291ec 10 *
boro 0:4beb2ea291ec 11 * The above copyright notice and this permission notice shall be included in
boro 0:4beb2ea291ec 12 * all copies or substantial portions of the Software.
boro 0:4beb2ea291ec 13 *
boro 0:4beb2ea291ec 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
boro 0:4beb2ea291ec 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
boro 0:4beb2ea291ec 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
boro 0:4beb2ea291ec 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
boro 0:4beb2ea291ec 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
boro 0:4beb2ea291ec 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
boro 0:4beb2ea291ec 20 * SOFTWARE.
boro 0:4beb2ea291ec 21 */
boro 0:4beb2ea291ec 22 #include "rtos/ConditionVariable.h"
boro 0:4beb2ea291ec 23 #include "rtos/Thread.h"
boro 0:4beb2ea291ec 24
boro 0:4beb2ea291ec 25 #include "mbed_error.h"
boro 0:4beb2ea291ec 26 #include "mbed_assert.h"
boro 0:4beb2ea291ec 27
boro 0:4beb2ea291ec 28 namespace rtos {
boro 0:4beb2ea291ec 29
boro 0:4beb2ea291ec 30
boro 0:4beb2ea291ec 31 ConditionVariable::Waiter::Waiter(): sem(0), prev(NULL), next(NULL), in_list(false)
boro 0:4beb2ea291ec 32 {
boro 0:4beb2ea291ec 33 // No initialization to do
boro 0:4beb2ea291ec 34 }
boro 0:4beb2ea291ec 35
boro 0:4beb2ea291ec 36 ConditionVariable::ConditionVariable(Mutex &mutex): _mutex(mutex), _wait_list(NULL)
boro 0:4beb2ea291ec 37 {
boro 0:4beb2ea291ec 38 // No initialization to do
boro 0:4beb2ea291ec 39 }
boro 0:4beb2ea291ec 40
boro 0:4beb2ea291ec 41 void ConditionVariable::wait()
boro 0:4beb2ea291ec 42 {
boro 0:4beb2ea291ec 43 wait_for(osWaitForever);
boro 0:4beb2ea291ec 44 }
boro 0:4beb2ea291ec 45
boro 0:4beb2ea291ec 46 bool ConditionVariable::wait_for(uint32_t millisec)
boro 0:4beb2ea291ec 47 {
boro 0:4beb2ea291ec 48 Waiter current_thread;
boro 0:4beb2ea291ec 49 MBED_ASSERT(_mutex.get_owner() == Thread::gettid());
boro 0:4beb2ea291ec 50 MBED_ASSERT(_mutex._count == 1);
boro 0:4beb2ea291ec 51 _add_wait_list(&_wait_list, &current_thread);
boro 0:4beb2ea291ec 52
boro 0:4beb2ea291ec 53 _mutex.unlock();
boro 0:4beb2ea291ec 54
boro 0:4beb2ea291ec 55 int32_t sem_count = current_thread.sem.wait(millisec);
boro 0:4beb2ea291ec 56 bool timeout = (sem_count > 0) ? false : true;
boro 0:4beb2ea291ec 57
boro 0:4beb2ea291ec 58 _mutex.lock();
boro 0:4beb2ea291ec 59
boro 0:4beb2ea291ec 60 if (current_thread.in_list) {
boro 0:4beb2ea291ec 61 _remove_wait_list(&_wait_list, &current_thread);
boro 0:4beb2ea291ec 62 }
boro 0:4beb2ea291ec 63
boro 0:4beb2ea291ec 64 return timeout;
boro 0:4beb2ea291ec 65 }
boro 0:4beb2ea291ec 66
boro 0:4beb2ea291ec 67 void ConditionVariable::notify_one()
boro 0:4beb2ea291ec 68 {
boro 0:4beb2ea291ec 69 MBED_ASSERT(_mutex.get_owner() == Thread::gettid());
boro 0:4beb2ea291ec 70 if (_wait_list != NULL) {
boro 0:4beb2ea291ec 71 _wait_list->sem.release();
boro 0:4beb2ea291ec 72 _remove_wait_list(&_wait_list, _wait_list);
boro 0:4beb2ea291ec 73 }
boro 0:4beb2ea291ec 74 }
boro 0:4beb2ea291ec 75
boro 0:4beb2ea291ec 76 void ConditionVariable::notify_all()
boro 0:4beb2ea291ec 77 {
boro 0:4beb2ea291ec 78 MBED_ASSERT(_mutex.get_owner() == Thread::gettid());
boro 0:4beb2ea291ec 79 while (_wait_list != NULL) {
boro 0:4beb2ea291ec 80 _wait_list->sem.release();
boro 0:4beb2ea291ec 81 _remove_wait_list(&_wait_list, _wait_list);
boro 0:4beb2ea291ec 82 }
boro 0:4beb2ea291ec 83 }
boro 0:4beb2ea291ec 84
boro 0:4beb2ea291ec 85 void ConditionVariable::_add_wait_list(Waiter **wait_list, Waiter *waiter)
boro 0:4beb2ea291ec 86 {
boro 0:4beb2ea291ec 87 if (NULL == *wait_list) {
boro 0:4beb2ea291ec 88 // Nothing in the list so add it directly.
boro 0:4beb2ea291ec 89 // Update prev and next pointer to reference self
boro 0:4beb2ea291ec 90 *wait_list = waiter;
boro 0:4beb2ea291ec 91 waiter->next = waiter;
boro 0:4beb2ea291ec 92 waiter->prev = waiter;
boro 0:4beb2ea291ec 93 } else {
boro 0:4beb2ea291ec 94 // Add after the last element
boro 0:4beb2ea291ec 95 Waiter *first = *wait_list;
boro 0:4beb2ea291ec 96 Waiter *last = (*wait_list)->prev;
boro 0:4beb2ea291ec 97
boro 0:4beb2ea291ec 98 // Update new entry
boro 0:4beb2ea291ec 99 waiter->next = first;
boro 0:4beb2ea291ec 100 waiter->prev = last;
boro 0:4beb2ea291ec 101
boro 0:4beb2ea291ec 102 // Insert into the list
boro 0:4beb2ea291ec 103 first->prev = waiter;
boro 0:4beb2ea291ec 104 last->next = waiter;
boro 0:4beb2ea291ec 105 }
boro 0:4beb2ea291ec 106 waiter->in_list = true;
boro 0:4beb2ea291ec 107 }
boro 0:4beb2ea291ec 108
boro 0:4beb2ea291ec 109 void ConditionVariable::_remove_wait_list(Waiter **wait_list, Waiter *waiter)
boro 0:4beb2ea291ec 110 {
boro 0:4beb2ea291ec 111 Waiter *prev = waiter->prev;
boro 0:4beb2ea291ec 112 Waiter *next = waiter->next;
boro 0:4beb2ea291ec 113
boro 0:4beb2ea291ec 114 // Remove from list
boro 0:4beb2ea291ec 115 prev->next = waiter->next;
boro 0:4beb2ea291ec 116 next->prev = waiter->prev;
boro 0:4beb2ea291ec 117 *wait_list = waiter->next;
boro 0:4beb2ea291ec 118
boro 0:4beb2ea291ec 119 if (*wait_list == waiter) {
boro 0:4beb2ea291ec 120 // This was the last element in the list
boro 0:4beb2ea291ec 121 *wait_list = NULL;
boro 0:4beb2ea291ec 122 }
boro 0:4beb2ea291ec 123
boro 0:4beb2ea291ec 124 // Invalidate pointers
boro 0:4beb2ea291ec 125 waiter->next = NULL;
boro 0:4beb2ea291ec 126 waiter->prev = NULL;
boro 0:4beb2ea291ec 127 waiter->in_list = false;
boro 0:4beb2ea291ec 128 }
boro 0:4beb2ea291ec 129
boro 0:4beb2ea291ec 130 ConditionVariable::~ConditionVariable()
boro 0:4beb2ea291ec 131 {
boro 0:4beb2ea291ec 132 MBED_ASSERT(NULL == _wait_list);
boro 0:4beb2ea291ec 133 }
boro 0:4beb2ea291ec 134
boro 0:4beb2ea291ec 135 }