mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CThunkBase.cpp Source File

CThunkBase.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2018-2018 ARM Limited
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 #include "platform/platform.h"
00019 #include "platform/mbed_critical.h"
00020 #include "platform/mbed_assert.h"
00021 #include "platform/mbed_error.h"
00022 
00023 
00024 #include "CThunkBase.h"
00025 
00026 MBED_STATIC_ASSERT(MBED_CONF_PLATFORM_CTHUNK_COUNT_MAX < 256, "MBED_CONF_PLATFORM_CTHUNK_COUNT_MAX must be less than 256");
00027 MBED_STATIC_ASSERT(MBED_CONF_PLATFORM_CTHUNK_COUNT_MAX > 0, "MBED_CONF_PLATFORM_CTHUNK_COUNT_MAX must be greater than 0");
00028 
00029 #define ENABLE_N(N) ((MBED_CONF_PLATFORM_CTHUNK_COUNT_MAX & N) ? 1 : 0)
00030 
00031 #define START_128   0
00032 #define START_64    (START_128 + ENABLE_N(128) * 128)
00033 #define START_32    (START_64  + ENABLE_N(64)  * 64)
00034 #define START_16    (START_32  + ENABLE_N(32)  * 32)
00035 #define START_8     (START_16  + ENABLE_N(16)  * 16)
00036 #define START_4     (START_8   + ENABLE_N(8)   * 8)
00037 #define START_2     (START_4   + ENABLE_N(4)   * 4)
00038 #define START_1     (START_2   + ENABLE_N(2)   * 2)
00039 
00040 #define DECLARE_THUNK128(start) \
00041     DECLARE_THUNK64(start),     \
00042     DECLARE_THUNK64(start + 64)
00043 #define DECLARE_THUNK64(start) \
00044     DECLARE_THUNK32(start),     \
00045     DECLARE_THUNK32(start + 32)
00046 #define DECLARE_THUNK32(start) \
00047     DECLARE_THUNK16(start),     \
00048     DECLARE_THUNK16(start + 16)
00049 #define DECLARE_THUNK16(start) \
00050     DECLARE_THUNK8(start),      \
00051     DECLARE_THUNK8(start + 8)
00052 #define DECLARE_THUNK8(start)  \
00053     DECLARE_THUNK4(start),      \
00054     DECLARE_THUNK4(start + 4)
00055 #define DECLARE_THUNK4(start)  \
00056     DECLARE_THUNK2(start),      \
00057     DECLARE_THUNK2(start + 2)
00058 #define DECLARE_THUNK2(start)  \
00059     DECLARE_THUNK1(start),       \
00060     DECLARE_THUNK1(start + 1)
00061 #define DECLARE_THUNK1(index)  &CThunkBase::thunk_entry<index>
00062 
00063 const CThunkEntry CThunkBase::_thunk_table[MBED_CONF_PLATFORM_CTHUNK_COUNT_MAX] = {
00064 #if ENABLE_N(128)
00065     DECLARE_THUNK128(START_128),
00066 #endif
00067 #if ENABLE_N(64)
00068     DECLARE_THUNK64(START_64),
00069 #endif
00070 #if ENABLE_N(32)
00071     DECLARE_THUNK32(START_32),
00072 #endif
00073 #if ENABLE_N(16)
00074     DECLARE_THUNK16(START_16),
00075 #endif
00076 #if ENABLE_N(8)
00077     DECLARE_THUNK8(START_8),
00078 #endif
00079 #if ENABLE_N(4)
00080     DECLARE_THUNK4(START_4),
00081 #endif
00082 #if ENABLE_N(2)
00083     DECLARE_THUNK2(START_2),
00084 #endif
00085 #if ENABLE_N(1)
00086     DECLARE_THUNK1(START_1)
00087 #endif
00088 };
00089 
00090 CThunkBase *CThunkBase::_thunk_storage[MBED_CONF_PLATFORM_CTHUNK_COUNT_MAX];
00091 
00092 CThunkBase::CthunkFree CThunkBase::_cthunk_free_real = NULL;
00093 
00094 CThunkEntry CThunkBase::cthunk_alloc(CThunkBase *cthunk)
00095 {
00096     // Atomically allocate one entry
00097     core_util_critical_section_enter();
00098     CThunkEntry entry = NULL;
00099     for (int i = 0; i < MBED_CONF_PLATFORM_CTHUNK_COUNT_MAX; i++) {
00100         if (_thunk_storage[i] == NULL) {
00101             _thunk_storage[i] = cthunk;
00102             entry = _thunk_table[i];
00103             break;
00104         }
00105     }
00106     core_util_critical_section_exit();
00107 
00108     if (entry == NULL) {
00109         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_OUT_OF_RESOURCES), "Ran out of CThunk entries. Increase MBED_CONF_PLATFORM_CTHUNK_COUNT_MAX to fix this error");
00110     }
00111 
00112     // Set function pointer on first use. This allows _thunk_table
00113     // and _thunk_storage to get removed by the linker if
00114     // cthunk_alloc is never used.
00115     _cthunk_free_real = &cthunk_free_real;
00116 
00117     return entry;
00118 }
00119 
00120 void CThunkBase::cthunk_free(CThunkEntry item)
00121 {
00122     if (_cthunk_free_real) {
00123         _cthunk_free_real(item);
00124     }
00125 }
00126 
00127 void CThunkBase::cthunk_free_real(CThunkEntry item)
00128 {
00129     bool found = false;
00130 
00131     core_util_critical_section_enter();
00132     for (int i = 0; i < MBED_CONF_PLATFORM_CTHUNK_COUNT_MAX; i++) {
00133         if (_thunk_table[i] == item) {
00134             _thunk_storage[i] = NULL;
00135             found = true;
00136             break;
00137         }
00138     }
00139     core_util_critical_section_exit();
00140 
00141     if (!found) {
00142         MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_INVALID_ARGUMENT), "Tried to free invalid CThunkEntry");
00143     }
00144 
00145 }