Simple interface for Mbed Cloud Client
Embed:
(wiki syntax)
Show/hide line numbers
ns_event_loop.c
00001 // ---------------------------------------------------------------------------- 00002 // Copyright 2016-2017 ARM Ltd. 00003 // 00004 // SPDX-License-Identifier: Apache-2.0 00005 // 00006 // Licensed under the Apache License, Version 2.0 (the "License"); 00007 // you may not use this file except in compliance with the License. 00008 // You may obtain a copy of the License at 00009 // 00010 // http://www.apache.org/licenses/LICENSE-2.0 00011 // 00012 // Unless required by applicable law or agreed to in writing, software 00013 // distributed under the License is distributed on an "AS IS" BASIS, 00014 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 // See the License for the specific language governing permissions and 00016 // limitations under the License. 00017 // ---------------------------------------------------------------------------- 00018 00019 #include "ns_event_loop.h" 00020 00021 #include "pal.h" 00022 #include "ns_trace.h" 00023 00024 #include "eventOS_scheduler.h" 00025 00026 #include <assert.h> 00027 00028 00029 #define TRACE_GROUP "evlp" 00030 00031 static void event_loop_thread(const void *arg); 00032 00033 static palThreadID_t event_thread_id = 0; 00034 static palMutexID_t event_mutex_id = 0; 00035 static palSemaphoreID_t event_start_sema_id = 0; 00036 static palSemaphoreID_t event_signal_sema_id = 0; 00037 static palSemaphoreID_t event_stop_sema_id = 0; 00038 static volatile bool event_stop_loop; 00039 00040 void eventOS_scheduler_mutex_wait(void) 00041 { 00042 palStatus_t status; 00043 status = pal_osMutexWait(event_mutex_id, UINT32_MAX); 00044 assert(PAL_SUCCESS == status); 00045 } 00046 00047 void eventOS_scheduler_mutex_release(void) 00048 { 00049 palStatus_t status; 00050 status = pal_osMutexRelease(event_mutex_id); 00051 assert(PAL_SUCCESS == status); 00052 } 00053 00054 void eventOS_scheduler_signal(void) 00055 { 00056 palStatus_t status; 00057 status = pal_osSemaphoreRelease(event_signal_sema_id); 00058 assert(PAL_SUCCESS == status); 00059 } 00060 00061 void eventOS_scheduler_idle(void) 00062 { 00063 int32_t counters = 0; 00064 palStatus_t status; 00065 00066 eventOS_scheduler_mutex_release(); 00067 00068 status = pal_osSemaphoreWait(event_signal_sema_id, UINT32_MAX, &counters); 00069 assert(PAL_SUCCESS == status); 00070 00071 eventOS_scheduler_mutex_wait(); 00072 } 00073 00074 static void event_loop_thread(const void *arg) 00075 { 00076 int32_t counters = 0; 00077 palStatus_t status; 00078 00079 tr_debug("event_loop_thread create"); 00080 00081 event_stop_loop = false; 00082 00083 status = pal_osSemaphoreWait(event_start_sema_id, UINT32_MAX, &counters); 00084 assert(PAL_SUCCESS == status); 00085 00086 // TODO: Delete start semaphore? 00087 eventOS_scheduler_mutex_wait(); 00088 tr_debug("event_loop_thread loop start"); 00089 00090 // A stoppable version of eventOS_scheduler_run(void) 00091 while (event_stop_loop == false) { 00092 if (!eventOS_scheduler_dispatch_event()) { 00093 eventOS_scheduler_idle(); 00094 } 00095 } 00096 tr_debug("event_loop_thread loop end"); 00097 00098 // cleanup the scheduler timer resources which are not needed anymore 00099 eventOS_scheduler_timer_stop(); 00100 00101 // signal the ns_event_loop_thread_stop() that it can continue 00102 status = pal_osSemaphoreRelease(event_stop_sema_id); 00103 assert(PAL_SUCCESS == status); 00104 } 00105 00106 void ns_event_loop_thread_create(void) 00107 { 00108 int32_t counters = 0; 00109 palStatus_t status; 00110 00111 status = pal_osSemaphoreCreate(1, &event_start_sema_id); 00112 assert(PAL_SUCCESS == status); 00113 00114 status = pal_osSemaphoreWait(event_start_sema_id, UINT32_MAX, &counters); 00115 assert(PAL_SUCCESS == status); 00116 00117 status = pal_osSemaphoreCreate(0, &event_stop_sema_id); 00118 assert(PAL_SUCCESS == status); 00119 00120 status = pal_osSemaphoreCreate(1, &event_signal_sema_id); 00121 assert(PAL_SUCCESS == status); 00122 00123 status = pal_osMutexCreate(&event_mutex_id); 00124 assert(PAL_SUCCESS == status); 00125 00126 status = pal_osThreadCreateWithAlloc(event_loop_thread, NULL, PAL_osPriorityNormal, MBED_CONF_NS_HAL_PAL_EVENT_LOOP_THREAD_STACK_SIZE, NULL, &event_thread_id); 00127 assert(PAL_SUCCESS == status); 00128 } 00129 00130 void ns_event_loop_thread_start(void) 00131 { 00132 palStatus_t status; 00133 status = pal_osSemaphoreRelease(event_start_sema_id); 00134 assert(PAL_SUCCESS == status); 00135 } 00136 00137 void ns_event_loop_thread_stop(void) 00138 { 00139 palStatus_t status; 00140 00141 // request loop to stop 00142 event_stop_loop = true; 00143 00144 // Ping the even loop at least once more so it will notice the flag and 00145 // hopefully end the loop soon. 00146 eventOS_scheduler_signal(); 00147 00148 // wait until the event loop has been stopped and the thread is shutting down. 00149 // Note: the PAL API does not have any better means to join with a thread termination. 00150 status = pal_osSemaphoreWait(event_stop_sema_id, UINT32_MAX, NULL); 00151 assert(PAL_SUCCESS == status); 00152 00153 pal_osSemaphoreDelete(&event_start_sema_id); 00154 pal_osSemaphoreDelete(&event_stop_sema_id); 00155 }
Generated on Tue Jul 12 2022 19:01:35 by 1.7.2