Azure IoT common library
Fork of azure_c_shared_utility by
threadapi_rtx_mbed.cpp
- Committer:
- Azure.IoT Build
- Date:
- 2016-07-01
- Revision:
- 6:c55b013dfc2a
- Parent:
- 1:9190c0f4d23a
- Child:
- 19:2e0811512ceb
File content as of revision 6:c55b013dfc2a:
// Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. #include <stdlib.h> #ifdef _CRTDBG_MAP_ALLOC #include <crtdbg.h> #endif #include "azure_c_shared_utility/threadapi.h" #include "azure_c_shared_utility/xlogging.h" #include "rtos.h" DEFINE_ENUM_STRINGS(THREADAPI_RESULT, THREADAPI_RESULT_VALUES); #define MAX_THREADS 4 #define STACK_SIZE 0x4000 typedef struct _thread { Thread* thrd; osThreadId id; Queue<int, 1> result; } mbedThread; static mbedThread threads[MAX_THREADS] = { 0 }; typedef struct _create_param { THREAD_START_FUNC func; const void* arg; mbedThread *p_thread; } create_param; static void thread_wrapper(const void* createParamArg) { const create_param* p = (const create_param*)createParamArg; p->p_thread->id = Thread::gettid(); (*(p->func))((void*)p->arg); free((void*)p); } THREADAPI_RESULT ThreadAPI_Create(THREAD_HANDLE* threadHandle, THREAD_START_FUNC func, void* arg) { THREADAPI_RESULT result; if ((threadHandle == NULL) || (func == NULL)) { result = THREADAPI_INVALID_ARG; LogError("(result = %s)", ENUM_TO_STRING(THREADAPI_RESULT, result)); } else { size_t slot; for (slot = 0; slot < MAX_THREADS; slot++) { if (threads[slot].id == NULL) break; } if (slot < MAX_THREADS) { create_param* param = (create_param*)malloc(sizeof(create_param)); if (param != NULL) { param->func = func; param->arg = arg; param->p_thread = threads + slot; threads[slot].thrd = new Thread(thread_wrapper, param, osPriorityNormal, STACK_SIZE); *threadHandle = (THREAD_HANDLE)(threads + slot); result = THREADAPI_OK; } else { result = THREADAPI_NO_MEMORY; LogError("(result = %s)", ENUM_TO_STRING(THREADAPI_RESULT, result)); } } else { result = THREADAPI_NO_MEMORY; LogError("(result = %s)", ENUM_TO_STRING(THREADAPI_RESULT, result)); } } return result; } THREADAPI_RESULT ThreadAPI_Join(THREAD_HANDLE thr, int *res) { THREADAPI_RESULT result = THREADAPI_OK; mbedThread* p = (mbedThread*)thr; if (p) { osEvent evt = p->result.get(); if (evt.status == osEventMessage) { Thread* t = p->thrd; if (res) { *res = (int)evt.value.p; } (void)t->terminate(); } else { result = THREADAPI_ERROR; LogError("(result = %s)", ENUM_TO_STRING(THREADAPI_RESULT, result)); } } else { result = THREADAPI_INVALID_ARG; LogError("(result = %s)", ENUM_TO_STRING(THREADAPI_RESULT, result)); } return result; } void ThreadAPI_Exit(int res) { mbedThread* p; for (p = threads; p < &threads[MAX_THREADS]; p++) { if (p->id == Thread::gettid()) { p->result.put((int*)res); break; } } } void ThreadAPI_Sleep(unsigned int millisec) { // // The timer on mbed seems to wrap around 65 seconds. Hmmm. // So we will do our waits in increments of 30 seconds. // const int thirtySeconds = 30000; int numberOfThirtySecondWaits = millisec / thirtySeconds; int remainderOfThirtySeconds = millisec % thirtySeconds; int i; for (i = 1; i <= numberOfThirtySecondWaits; i++) { Thread::wait(thirtySeconds); } Thread::wait(remainderOfThirtySeconds); }