| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- // 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>
- #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);
- }
|