Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
ThisThread.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2012 ARM Limited 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a copy 00005 * of this software and associated documentation files (the "Software"), to deal 00006 * in the Software without restriction, including without limitation the rights 00007 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00008 * copies of the Software, and to permit persons to whom the Software is 00009 * furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included in 00012 * all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00017 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00019 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00020 * SOFTWARE. 00021 */ 00022 00023 #define __STDC_LIMIT_MACROS 00024 #include "rtos/ThisThread.h" 00025 00026 #include "platform/mbed_toolchain.h" 00027 #include "rtos/Kernel.h" 00028 #include "platform/CriticalSectionLock.h" 00029 #include "platform/mbed_assert.h" 00030 #include "platform/mbed_critical.h" 00031 #include "platform/source/mbed_os_timer.h" 00032 00033 #if !MBED_CONF_RTOS_PRESENT 00034 /* If the RTOS is not present, we call mbed_thread.cpp to do the work */ 00035 /* If the RTOS is present, mbed_thread.cpp calls us to do the work */ 00036 #include "platform/mbed_thread.h" 00037 00038 static uint32_t thread_flags; 00039 00040 /* For the flags to be useful, need a way of setting them, but there's only the main 00041 * thread, and that has no Thread object, so Thread class is not provided. Implement 00042 * one CMSIS-RTOS function to provide access. 00043 */ 00044 extern "C" 00045 uint32_t osThreadFlagsSet(osThreadId_t /*thread_id*/, uint32_t flags) 00046 { 00047 return core_util_atomic_fetch_or_u32 (&thread_flags, flags) | flags; 00048 } 00049 #endif 00050 00051 namespace rtos { 00052 00053 uint32_t ThisThread::flags_clear(uint32_t flags) 00054 { 00055 #if MBED_CONF_RTOS_PRESENT 00056 flags = osThreadFlagsClear(flags); 00057 MBED_ASSERT(!(flags & osFlagsError)); 00058 #else 00059 flags = core_util_atomic_fetch_and_u32 (&thread_flags, ~flags); 00060 #endif 00061 return flags; 00062 } 00063 00064 uint32_t ThisThread::flags_get() 00065 { 00066 #if MBED_CONF_RTOS_PRESENT 00067 return osThreadFlagsGet(); 00068 #else 00069 return core_util_atomic_load_u32 (&thread_flags); 00070 #endif 00071 } 00072 00073 #if !MBED_CONF_RTOS_PRESENT 00074 namespace internal { 00075 bool non_rtos_check_flags(void *handle) 00076 { 00077 flags_check_capture *check = static_cast<flags_check_capture *>(handle); 00078 uint32_t cur_flags = core_util_atomic_load_u32 (check->flags); 00079 uint32_t set_flags; 00080 do { 00081 set_flags = cur_flags & check->flags_wanted; 00082 check->result = set_flags; 00083 if ((check->options & osFlagsWaitAll) ? set_flags == check->flags_wanted : set_flags != 0) { 00084 if (check->options & osFlagsNoClear) { 00085 break; 00086 } 00087 } else { 00088 return false; 00089 } 00090 } while (!core_util_atomic_cas_u32 (check->flags, &cur_flags, cur_flags & ~set_flags)); 00091 check->match = true; 00092 return true; 00093 } 00094 } 00095 #endif 00096 00097 static uint32_t flags_wait_for(uint32_t flags, uint32_t millisec, bool clear, uint32_t options) 00098 { 00099 if (!clear) { 00100 options |= osFlagsNoClear; 00101 } 00102 #if MBED_CONF_RTOS_PRESENT 00103 flags = osThreadFlagsWait(flags, options, millisec); 00104 if (flags & osFlagsError) { 00105 MBED_ASSERT((flags == osFlagsErrorTimeout && millisec != osWaitForever) || 00106 (flags == osFlagsErrorResource && millisec == 0)); 00107 flags = ThisThread::flags_get(); 00108 } 00109 #else 00110 rtos::internal::flags_check_capture check; 00111 check.flags = &thread_flags; 00112 check.options = options; 00113 check.flags_wanted = flags; 00114 check.result = 0; 00115 mbed::internal::do_timed_sleep_relative_or_forever(millisec, rtos::internal::non_rtos_check_flags, &check); 00116 flags = check.result; 00117 #endif 00118 00119 return flags; 00120 } 00121 00122 static uint32_t flags_wait(uint32_t flags, bool clear, uint32_t options) 00123 { 00124 #if MBED_CONF_RTOS_PRESENT 00125 return flags_wait_for(flags, osWaitForever, clear, options); 00126 #else 00127 /* Avoids pulling in timer if not used */ 00128 if (!clear) { 00129 options |= osFlagsNoClear; 00130 } 00131 rtos::internal::flags_check_capture check; 00132 check.flags = &thread_flags; 00133 check.options = options; 00134 check.flags_wanted = flags; 00135 check.result = 0; 00136 mbed::internal::do_untimed_sleep(rtos::internal::non_rtos_check_flags, &check); 00137 flags = check.result; 00138 00139 return flags; 00140 #endif 00141 } 00142 00143 static uint32_t flags_wait_until(uint32_t flags, uint64_t millisec, bool clear, uint32_t options) 00144 { 00145 uint64_t now = Kernel::get_ms_count(); 00146 00147 uint32_t delay; 00148 if (now >= millisec) { 00149 delay = 0; 00150 } else if (millisec - now >= osWaitForever) { 00151 // Documentation permits early return for big offsets 00152 delay = osWaitForever - 1; 00153 } else { 00154 delay = millisec - now; 00155 } 00156 return flags_wait_for(flags, delay, clear, options); 00157 } 00158 00159 uint32_t ThisThread::flags_wait_all(uint32_t flags, bool clear) 00160 { 00161 return flags_wait(flags, clear, osFlagsWaitAll); 00162 } 00163 00164 uint32_t ThisThread::flags_wait_all_for(uint32_t flags, uint32_t millisec, bool clear) 00165 { 00166 return flags_wait_for(flags, millisec, clear, osFlagsWaitAll); 00167 } 00168 00169 uint32_t ThisThread::flags_wait_all_until(uint32_t flags, uint64_t millisec, bool clear) 00170 { 00171 return flags_wait_until(flags, millisec, clear, osFlagsWaitAll); 00172 } 00173 00174 uint32_t ThisThread::flags_wait_any(uint32_t flags, bool clear) 00175 { 00176 return flags_wait(flags, clear, osFlagsWaitAny); 00177 } 00178 00179 uint32_t ThisThread::flags_wait_any_for(uint32_t flags, uint32_t millisec, bool clear) 00180 { 00181 return flags_wait_for(flags, millisec, clear, osFlagsWaitAny); 00182 } 00183 00184 uint32_t ThisThread::flags_wait_any_until(uint32_t flags, uint64_t millisec, bool clear) 00185 { 00186 return flags_wait_until(flags, millisec, clear, osFlagsWaitAny); 00187 } 00188 00189 void ThisThread::sleep_for(uint32_t millisec) 00190 { 00191 #if MBED_CONF_RTOS_PRESENT 00192 osStatus_t status = osDelay(millisec); 00193 MBED_ASSERT(status == osOK); 00194 #else 00195 thread_sleep_for(millisec); 00196 #endif 00197 } 00198 00199 void ThisThread::sleep_until(uint64_t millisec) 00200 { 00201 #if MBED_CONF_RTOS_PRESENT 00202 // CMSIS-RTOS 2.1.0 had 64-bit time and osDelayUntil, but that's been revoked. 00203 // Limit ourselves to manual implementation assuming a >=32-bit osDelay. 00204 00205 // 64-bit time doesn't wrap (for half a billion years, at last) 00206 // make the effort to loop for unlimited sleep, as it doesn't cost much 00207 uint64_t now; 00208 00209 while ((now = Kernel::get_ms_count()) < millisec) { 00210 if (millisec - now > UINT32_MAX) { 00211 sleep_for(UINT32_MAX); 00212 continue; 00213 } else { 00214 sleep_for(millisec - now); 00215 break; 00216 } 00217 } 00218 #else 00219 thread_sleep_until(millisec); 00220 #endif 00221 } 00222 00223 void ThisThread::yield() 00224 { 00225 #if MBED_CONF_RTOS_PRESENT 00226 osThreadYield(); 00227 #else 00228 asm("yield"); 00229 #endif 00230 } 00231 00232 osThreadId_t ThisThread::get_id() 00233 { 00234 #if MBED_CONF_RTOS_PRESENT 00235 return osThreadGetId(); 00236 #else 00237 return (osThreadId_t) 1; // dummy non-0 value 00238 #endif 00239 } 00240 00241 const char *get_name() 00242 { 00243 #if MBED_CONF_RTOS_PRESENT 00244 osThreadId_t id = osThreadGetId(); 00245 if (id == nullptr) { 00246 return nullptr; 00247 } 00248 return osThreadGetName(id); 00249 #else 00250 return nullptr; 00251 #endif 00252 } 00253 00254 }
Generated on Tue Jul 12 2022 13:54:57 by
