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.
Fork of azure_c_shared_utility by
threadapi_rtx_mbed.cpp@6:c55b013dfc2a, 2016-07-01 (annotated)
- Committer:
- Azure.IoT Build
- Date:
- Fri Jul 01 10:43:23 2016 -0700
- Revision:
- 6:c55b013dfc2a
- Parent:
- 1:9190c0f4d23a
- Child:
- 19:2e0811512ceb
1.0.10
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| Azure.IoT Build | 0:fa2de1b79154 | 1 | // Copyright (c) Microsoft. All rights reserved. |
| Azure.IoT Build | 0:fa2de1b79154 | 2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information. |
| Azure.IoT Build | 0:fa2de1b79154 | 3 | |
| Azure.IoT Build | 0:fa2de1b79154 | 4 | #include <stdlib.h> |
| Azure.IoT Build | 0:fa2de1b79154 | 5 | #ifdef _CRTDBG_MAP_ALLOC |
| Azure.IoT Build | 0:fa2de1b79154 | 6 | #include <crtdbg.h> |
| Azure.IoT Build | 0:fa2de1b79154 | 7 | #endif |
| Azure.IoT Build | 0:fa2de1b79154 | 8 | |
| Azure.IoT Build | 0:fa2de1b79154 | 9 | #include "azure_c_shared_utility/threadapi.h" |
| Azure.IoT Build | 6:c55b013dfc2a | 10 | #include "azure_c_shared_utility/xlogging.h" |
| Azure.IoT Build | 0:fa2de1b79154 | 11 | #include "rtos.h" |
| Azure.IoT Build | 0:fa2de1b79154 | 12 | |
| Azure.IoT Build | 0:fa2de1b79154 | 13 | DEFINE_ENUM_STRINGS(THREADAPI_RESULT, THREADAPI_RESULT_VALUES); |
| Azure.IoT Build | 0:fa2de1b79154 | 14 | |
| Azure.IoT Build | 0:fa2de1b79154 | 15 | #define MAX_THREADS 4 |
| Azure.IoT Build | 0:fa2de1b79154 | 16 | #define STACK_SIZE 0x4000 |
| Azure.IoT Build | 0:fa2de1b79154 | 17 | |
| Azure.IoT Build | 0:fa2de1b79154 | 18 | typedef struct _thread |
| Azure.IoT Build | 0:fa2de1b79154 | 19 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 20 | Thread* thrd; |
| Azure.IoT Build | 0:fa2de1b79154 | 21 | osThreadId id; |
| Azure.IoT Build | 0:fa2de1b79154 | 22 | Queue<int, 1> result; |
| Azure.IoT Build | 0:fa2de1b79154 | 23 | } mbedThread; |
| Azure.IoT Build | 0:fa2de1b79154 | 24 | static mbedThread threads[MAX_THREADS] = { 0 }; |
| Azure.IoT Build | 0:fa2de1b79154 | 25 | |
| Azure.IoT Build | 0:fa2de1b79154 | 26 | typedef struct _create_param |
| Azure.IoT Build | 0:fa2de1b79154 | 27 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 28 | THREAD_START_FUNC func; |
| Azure.IoT Build | 0:fa2de1b79154 | 29 | const void* arg; |
| Azure.IoT Build | 0:fa2de1b79154 | 30 | mbedThread *p_thread; |
| Azure.IoT Build | 0:fa2de1b79154 | 31 | } create_param; |
| Azure.IoT Build | 0:fa2de1b79154 | 32 | |
| Azure.IoT Build | 0:fa2de1b79154 | 33 | static void thread_wrapper(const void* createParamArg) |
| Azure.IoT Build | 0:fa2de1b79154 | 34 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 35 | const create_param* p = (const create_param*)createParamArg; |
| Azure.IoT Build | 0:fa2de1b79154 | 36 | p->p_thread->id = Thread::gettid(); |
| Azure.IoT Build | 0:fa2de1b79154 | 37 | (*(p->func))((void*)p->arg); |
| Azure.IoT Build | 0:fa2de1b79154 | 38 | free((void*)p); |
| Azure.IoT Build | 0:fa2de1b79154 | 39 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 40 | |
| Azure.IoT Build | 0:fa2de1b79154 | 41 | THREADAPI_RESULT ThreadAPI_Create(THREAD_HANDLE* threadHandle, THREAD_START_FUNC func, void* arg) |
| Azure.IoT Build | 0:fa2de1b79154 | 42 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 43 | THREADAPI_RESULT result; |
| Azure.IoT Build | 0:fa2de1b79154 | 44 | if ((threadHandle == NULL) || |
| Azure.IoT Build | 0:fa2de1b79154 | 45 | (func == NULL)) |
| Azure.IoT Build | 0:fa2de1b79154 | 46 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 47 | result = THREADAPI_INVALID_ARG; |
| AzureIoTClient | 1:9190c0f4d23a | 48 | LogError("(result = %s)", ENUM_TO_STRING(THREADAPI_RESULT, result)); |
| Azure.IoT Build | 0:fa2de1b79154 | 49 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 50 | else |
| Azure.IoT Build | 0:fa2de1b79154 | 51 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 52 | size_t slot; |
| Azure.IoT Build | 0:fa2de1b79154 | 53 | for (slot = 0; slot < MAX_THREADS; slot++) |
| Azure.IoT Build | 0:fa2de1b79154 | 54 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 55 | if (threads[slot].id == NULL) |
| Azure.IoT Build | 0:fa2de1b79154 | 56 | break; |
| Azure.IoT Build | 0:fa2de1b79154 | 57 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 58 | |
| Azure.IoT Build | 0:fa2de1b79154 | 59 | if (slot < MAX_THREADS) |
| Azure.IoT Build | 0:fa2de1b79154 | 60 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 61 | create_param* param = (create_param*)malloc(sizeof(create_param)); |
| Azure.IoT Build | 0:fa2de1b79154 | 62 | if (param != NULL) |
| Azure.IoT Build | 0:fa2de1b79154 | 63 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 64 | param->func = func; |
| Azure.IoT Build | 0:fa2de1b79154 | 65 | param->arg = arg; |
| Azure.IoT Build | 0:fa2de1b79154 | 66 | param->p_thread = threads + slot; |
| Azure.IoT Build | 0:fa2de1b79154 | 67 | threads[slot].thrd = new Thread(thread_wrapper, param, osPriorityNormal, STACK_SIZE); |
| Azure.IoT Build | 0:fa2de1b79154 | 68 | *threadHandle = (THREAD_HANDLE)(threads + slot); |
| Azure.IoT Build | 0:fa2de1b79154 | 69 | result = THREADAPI_OK; |
| Azure.IoT Build | 0:fa2de1b79154 | 70 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 71 | else |
| Azure.IoT Build | 0:fa2de1b79154 | 72 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 73 | result = THREADAPI_NO_MEMORY; |
| AzureIoTClient | 1:9190c0f4d23a | 74 | LogError("(result = %s)", ENUM_TO_STRING(THREADAPI_RESULT, result)); |
| Azure.IoT Build | 0:fa2de1b79154 | 75 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 76 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 77 | else |
| Azure.IoT Build | 0:fa2de1b79154 | 78 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 79 | result = THREADAPI_NO_MEMORY; |
| AzureIoTClient | 1:9190c0f4d23a | 80 | LogError("(result = %s)", ENUM_TO_STRING(THREADAPI_RESULT, result)); |
| Azure.IoT Build | 0:fa2de1b79154 | 81 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 82 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 83 | |
| Azure.IoT Build | 0:fa2de1b79154 | 84 | return result; |
| Azure.IoT Build | 0:fa2de1b79154 | 85 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 86 | |
| Azure.IoT Build | 0:fa2de1b79154 | 87 | THREADAPI_RESULT ThreadAPI_Join(THREAD_HANDLE thr, int *res) |
| Azure.IoT Build | 0:fa2de1b79154 | 88 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 89 | THREADAPI_RESULT result = THREADAPI_OK; |
| Azure.IoT Build | 0:fa2de1b79154 | 90 | mbedThread* p = (mbedThread*)thr; |
| Azure.IoT Build | 0:fa2de1b79154 | 91 | if (p) |
| Azure.IoT Build | 0:fa2de1b79154 | 92 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 93 | osEvent evt = p->result.get(); |
| Azure.IoT Build | 0:fa2de1b79154 | 94 | if (evt.status == osEventMessage) { |
| Azure.IoT Build | 0:fa2de1b79154 | 95 | Thread* t = p->thrd; |
| Azure.IoT Build | 0:fa2de1b79154 | 96 | if (res) |
| Azure.IoT Build | 0:fa2de1b79154 | 97 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 98 | *res = (int)evt.value.p; |
| Azure.IoT Build | 0:fa2de1b79154 | 99 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 100 | (void)t->terminate(); |
| Azure.IoT Build | 0:fa2de1b79154 | 101 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 102 | else |
| Azure.IoT Build | 0:fa2de1b79154 | 103 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 104 | result = THREADAPI_ERROR; |
| AzureIoTClient | 1:9190c0f4d23a | 105 | LogError("(result = %s)", ENUM_TO_STRING(THREADAPI_RESULT, result)); |
| Azure.IoT Build | 0:fa2de1b79154 | 106 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 107 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 108 | else |
| Azure.IoT Build | 0:fa2de1b79154 | 109 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 110 | result = THREADAPI_INVALID_ARG; |
| AzureIoTClient | 1:9190c0f4d23a | 111 | LogError("(result = %s)", ENUM_TO_STRING(THREADAPI_RESULT, result)); |
| Azure.IoT Build | 0:fa2de1b79154 | 112 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 113 | return result; |
| Azure.IoT Build | 0:fa2de1b79154 | 114 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 115 | |
| Azure.IoT Build | 0:fa2de1b79154 | 116 | void ThreadAPI_Exit(int res) |
| Azure.IoT Build | 0:fa2de1b79154 | 117 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 118 | mbedThread* p; |
| Azure.IoT Build | 0:fa2de1b79154 | 119 | for (p = threads; p < &threads[MAX_THREADS]; p++) |
| Azure.IoT Build | 0:fa2de1b79154 | 120 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 121 | if (p->id == Thread::gettid()) |
| Azure.IoT Build | 0:fa2de1b79154 | 122 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 123 | p->result.put((int*)res); |
| Azure.IoT Build | 0:fa2de1b79154 | 124 | break; |
| Azure.IoT Build | 0:fa2de1b79154 | 125 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 126 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 127 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 128 | |
| Azure.IoT Build | 0:fa2de1b79154 | 129 | void ThreadAPI_Sleep(unsigned int millisec) |
| Azure.IoT Build | 0:fa2de1b79154 | 130 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 131 | // |
| Azure.IoT Build | 0:fa2de1b79154 | 132 | // The timer on mbed seems to wrap around 65 seconds. Hmmm. |
| Azure.IoT Build | 0:fa2de1b79154 | 133 | // So we will do our waits in increments of 30 seconds. |
| Azure.IoT Build | 0:fa2de1b79154 | 134 | // |
| Azure.IoT Build | 0:fa2de1b79154 | 135 | const int thirtySeconds = 30000; |
| Azure.IoT Build | 0:fa2de1b79154 | 136 | int numberOfThirtySecondWaits = millisec / thirtySeconds; |
| Azure.IoT Build | 0:fa2de1b79154 | 137 | int remainderOfThirtySeconds = millisec % thirtySeconds; |
| Azure.IoT Build | 0:fa2de1b79154 | 138 | int i; |
| Azure.IoT Build | 0:fa2de1b79154 | 139 | for (i = 1; i <= numberOfThirtySecondWaits; i++) |
| Azure.IoT Build | 0:fa2de1b79154 | 140 | { |
| Azure.IoT Build | 0:fa2de1b79154 | 141 | Thread::wait(thirtySeconds); |
| Azure.IoT Build | 0:fa2de1b79154 | 142 | } |
| Azure.IoT Build | 0:fa2de1b79154 | 143 | Thread::wait(remainderOfThirtySeconds); |
| Azure.IoT Build | 0:fa2de1b79154 | 144 | } |
