|
25 | 25 |
|
26 | 26 | #define WOLFSENTRY_SOURCE_ID WOLFSENTRY_SOURCE_ID_WOLFSENTRY_UTIL_C |
27 | 27 |
|
| 28 | +#if !defined(WOLFSENTRY_HAVE_GNU_ATOMICS) && defined(THREADX) |
| 29 | +/* ThreadX atomic operations implementation - global mutex approach */ |
| 30 | +static TX_MUTEX wolfsentry_threadx_atomic_mutex; |
| 31 | +static int wolfsentry_threadx_atomic_mutex_initialized = 0; |
| 32 | + |
| 33 | +/* Initialize the global atomic mutex (call once at startup) */ |
| 34 | +int wolfsentry_threadx_atomic_init_global(void) { |
| 35 | + if (!wolfsentry_threadx_atomic_mutex_initialized) { |
| 36 | + if (tx_mutex_create(&wolfsentry_threadx_atomic_mutex, |
| 37 | + (char *)"WolfSentry_Global_Atomic", TX_NO_INHERIT) == TX_SUCCESS) { |
| 38 | + wolfsentry_threadx_atomic_mutex_initialized = 1; |
| 39 | + return 0; |
| 40 | + } |
| 41 | + return -1; |
| 42 | + } |
| 43 | + return 0; |
| 44 | +} |
| 45 | + |
| 46 | +/* Cleanup the global atomic mutex (call once at shutdown) */ |
| 47 | +void wolfsentry_threadx_atomic_cleanup_global(void) { |
| 48 | + if (wolfsentry_threadx_atomic_mutex_initialized) { |
| 49 | + tx_mutex_delete(&wolfsentry_threadx_atomic_mutex); |
| 50 | + wolfsentry_threadx_atomic_mutex_initialized = 0; |
| 51 | + } |
| 52 | +} |
| 53 | + |
| 54 | +/* ThreadX atomic operations using global mutex protection - type-generic using uintptr_t */ |
| 55 | +uintptr_t wolfsentry_threadx_atomic_add_fetch(volatile uintptr_t *ptr, uintptr_t x) { |
| 56 | + uintptr_t result; |
| 57 | + if (!wolfsentry_threadx_atomic_mutex_initialized) { |
| 58 | + wolfsentry_threadx_atomic_init_global(); |
| 59 | + } |
| 60 | + if (tx_mutex_get(&wolfsentry_threadx_atomic_mutex, TX_WAIT_FOREVER) != TX_SUCCESS) { |
| 61 | + return *ptr; /* Return current value on failure */ |
| 62 | + } |
| 63 | + *ptr += x; |
| 64 | + result = *ptr; |
| 65 | + tx_mutex_put(&wolfsentry_threadx_atomic_mutex); |
| 66 | + return result; |
| 67 | +} |
| 68 | + |
| 69 | +uintptr_t wolfsentry_threadx_atomic_sub_fetch(volatile uintptr_t *ptr, uintptr_t x) { |
| 70 | + uintptr_t result; |
| 71 | + if (!wolfsentry_threadx_atomic_mutex_initialized) { |
| 72 | + wolfsentry_threadx_atomic_init_global(); |
| 73 | + } |
| 74 | + if (tx_mutex_get(&wolfsentry_threadx_atomic_mutex, TX_WAIT_FOREVER) != TX_SUCCESS) { |
| 75 | + return *ptr; /* Return current value on failure */ |
| 76 | + } |
| 77 | + *ptr -= x; |
| 78 | + result = *ptr; |
| 79 | + tx_mutex_put(&wolfsentry_threadx_atomic_mutex); |
| 80 | + return result; |
| 81 | +} |
| 82 | + |
| 83 | +uintptr_t wolfsentry_threadx_atomic_fetch_add(volatile uintptr_t *ptr, uintptr_t x) { |
| 84 | + uintptr_t result; |
| 85 | + if (!wolfsentry_threadx_atomic_mutex_initialized) { |
| 86 | + wolfsentry_threadx_atomic_init_global(); |
| 87 | + } |
| 88 | + if (tx_mutex_get(&wolfsentry_threadx_atomic_mutex, TX_WAIT_FOREVER) != TX_SUCCESS) { |
| 89 | + return *ptr; /* Return current value on failure */ |
| 90 | + } |
| 91 | + result = *ptr; |
| 92 | + *ptr += x; |
| 93 | + tx_mutex_put(&wolfsentry_threadx_atomic_mutex); |
| 94 | + return result; |
| 95 | +} |
| 96 | + |
| 97 | +uintptr_t wolfsentry_threadx_atomic_fetch_sub(volatile uintptr_t *ptr, uintptr_t x) { |
| 98 | + uintptr_t result; |
| 99 | + if (!wolfsentry_threadx_atomic_mutex_initialized) { |
| 100 | + wolfsentry_threadx_atomic_init_global(); |
| 101 | + } |
| 102 | + if (tx_mutex_get(&wolfsentry_threadx_atomic_mutex, TX_WAIT_FOREVER) != TX_SUCCESS) { |
| 103 | + return *ptr; /* Return current value on failure */ |
| 104 | + } |
| 105 | + result = *ptr; |
| 106 | + *ptr -= x; |
| 107 | + tx_mutex_put(&wolfsentry_threadx_atomic_mutex); |
| 108 | + return result; |
| 109 | +} |
| 110 | + |
| 111 | +void wolfsentry_threadx_atomic_store(volatile uintptr_t *ptr, uintptr_t x) { |
| 112 | + if (!wolfsentry_threadx_atomic_mutex_initialized) { |
| 113 | + wolfsentry_threadx_atomic_init_global(); |
| 114 | + } |
| 115 | + if (tx_mutex_get(&wolfsentry_threadx_atomic_mutex, TX_WAIT_FOREVER) != TX_SUCCESS) { |
| 116 | + return; |
| 117 | + } |
| 118 | + *ptr = x; |
| 119 | + tx_mutex_put(&wolfsentry_threadx_atomic_mutex); |
| 120 | +} |
| 121 | + |
| 122 | +uintptr_t wolfsentry_threadx_atomic_load(volatile uintptr_t *ptr) { |
| 123 | + uintptr_t result; |
| 124 | + if (!wolfsentry_threadx_atomic_mutex_initialized) { |
| 125 | + wolfsentry_threadx_atomic_init_global(); |
| 126 | + } |
| 127 | + if (tx_mutex_get(&wolfsentry_threadx_atomic_mutex, TX_WAIT_FOREVER) != TX_SUCCESS) { |
| 128 | + return *ptr; /* Return current value on failure */ |
| 129 | + } |
| 130 | + result = *ptr; |
| 131 | + tx_mutex_put(&wolfsentry_threadx_atomic_mutex); |
| 132 | + return result; |
| 133 | +} |
| 134 | + |
| 135 | +int wolfsentry_threadx_atomic_compare_exchange(volatile uintptr_t *ptr, uintptr_t *expected, uintptr_t desired) { |
| 136 | + int success = 0; |
| 137 | + if (!wolfsentry_threadx_atomic_mutex_initialized) { |
| 138 | + wolfsentry_threadx_atomic_init_global(); |
| 139 | + } |
| 140 | + if (tx_mutex_get(&wolfsentry_threadx_atomic_mutex, TX_WAIT_FOREVER) != TX_SUCCESS) { |
| 141 | + return 0; |
| 142 | + } |
| 143 | + if (*ptr == *expected) { |
| 144 | + *ptr = desired; |
| 145 | + success = 1; |
| 146 | + } else { |
| 147 | + *expected = *ptr; |
| 148 | + } |
| 149 | + tx_mutex_put(&wolfsentry_threadx_atomic_mutex); |
| 150 | + return success; |
| 151 | +} |
| 152 | +#endif /* THREADX */ |
| 153 | + |
28 | 154 | #ifdef WOLFSENTRY_ERROR_STRINGS |
29 | 155 |
|
30 | 156 | static const char *user_defined_sources[WOLFSENTRY_SOURCE_ID_MAX - WOLFSENTRY_SOURCE_ID_USER_BASE + 1] = {0}; |
@@ -812,8 +938,10 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_init_thread_context(struct wolfse |
812 | 938 | * the held lock can be safely locked recursively from within the |
813 | 939 | * interrupt context. |
814 | 940 | */ |
815 | | - if (thread_context->id == (wolfsentry_thread_id_t)((uintptr_t)WOLFSENTRY_THREAD_NO_ID - 0xffffff)) |
816 | | - WOLFSENTRY_ATOMIC_INCREMENT(fallback_thread_id_counter, 0xffffff); |
| 941 | + if (thread_context->id == (wolfsentry_thread_id_t)((uintptr_t)WOLFSENTRY_THREAD_NO_ID - 0xffffff)) { |
| 942 | + (void)WOLFSENTRY_ATOMIC_INCREMENT(fallback_thread_id_counter, 0xffffff); |
| 943 | + } |
| 944 | + (void)fallback_thread_id_counter; |
817 | 945 | WOLFSENTRY_SUCCESS_RETURN(USED_FALLBACK); |
818 | 946 | } else |
819 | 947 | WOLFSENTRY_RETURN_OK; |
@@ -1509,6 +1637,73 @@ static int freertos_sem_destroy( sem_t * sem ) |
1509 | 1637 |
|
1510 | 1638 | #define sem_destroy freertos_sem_destroy |
1511 | 1639 |
|
| 1640 | +#elif defined(THREADX) |
| 1641 | + |
| 1642 | + #ifndef ETIMEDOUT |
| 1643 | + #define ETIMEDOUT 110 /* Connection timed out */ |
| 1644 | + #endif |
| 1645 | + |
| 1646 | + #define sem_init threadx_sem_init |
| 1647 | + static int threadx_sem_init( sem_t * sem, |
| 1648 | + int pshared, |
| 1649 | + unsigned value ) |
| 1650 | + { |
| 1651 | + (void)pshared; |
| 1652 | + if (tx_semaphore_create(sem, NULL, value) != TX_SUCCESS) { |
| 1653 | + errno = EINVAL; |
| 1654 | + WOLFSENTRY_RETURN_VALUE(-1); |
| 1655 | + } |
| 1656 | + WOLFSENTRY_RETURN_VALUE(0); |
| 1657 | + } |
| 1658 | + #define sem_post threadx_sem_post |
| 1659 | + static int threadx_sem_post( sem_t * sem ) |
| 1660 | + { |
| 1661 | + if (tx_semaphore_put(sem) != TX_SUCCESS) { |
| 1662 | + errno = EINVAL; |
| 1663 | + WOLFSENTRY_RETURN_VALUE(-1); |
| 1664 | + } |
| 1665 | + WOLFSENTRY_RETURN_VALUE(0); |
| 1666 | + } |
| 1667 | + #define sem_timedwait threadx_sem_timedwait |
| 1668 | + static int threadx_sem_timedwait( sem_t * sem, |
| 1669 | + const struct timespec * abstime ) |
| 1670 | + { |
| 1671 | + if (tx_semaphore_get(sem, (uint32_t)(TX_TICK_TIME_MS * |
| 1672 | + (abstime->tv_sec * 1000) + (abstime->tv_nsec / 1000000))) != TX_SUCCESS) { |
| 1673 | + errno = EINVAL; |
| 1674 | + WOLFSENTRY_RETURN_VALUE(-1); |
| 1675 | + } |
| 1676 | + WOLFSENTRY_RETURN_VALUE(0); |
| 1677 | + } |
| 1678 | + #define sem_wait threadx_sem_wait |
| 1679 | + static int threadx_sem_wait( sem_t * sem ) |
| 1680 | + { |
| 1681 | + if (tx_semaphore_get(sem, TX_WAIT_FOREVER) != TX_SUCCESS) { |
| 1682 | + errno = EINVAL; |
| 1683 | + WOLFSENTRY_RETURN_VALUE(-1); |
| 1684 | + } |
| 1685 | + WOLFSENTRY_RETURN_VALUE(0); |
| 1686 | + } |
| 1687 | + #define sem_trywait threadx_sem_trywait |
| 1688 | + static int threadx_sem_trywait( sem_t * sem ) |
| 1689 | + { |
| 1690 | + if (tx_semaphore_get(sem, 0) != TX_SUCCESS) { |
| 1691 | + errno = EINVAL; |
| 1692 | + WOLFSENTRY_RETURN_VALUE(-1); |
| 1693 | + } |
| 1694 | + WOLFSENTRY_RETURN_VALUE(0); |
| 1695 | + } |
| 1696 | + static int threadx_sem_destroy( sem_t * sem ) |
| 1697 | + { |
| 1698 | + if (tx_semaphore_delete(sem) != TX_SUCCESS) { |
| 1699 | + errno = EINVAL; |
| 1700 | + WOLFSENTRY_RETURN_VALUE(-1); |
| 1701 | + } |
| 1702 | + WOLFSENTRY_RETURN_VALUE(0); |
| 1703 | + } |
| 1704 | + |
| 1705 | + #define sem_destroy threadx_sem_destroy |
| 1706 | + |
1512 | 1707 | #else |
1513 | 1708 |
|
1514 | 1709 | #error Semaphore builtins not implemented for target -- build wolfSentry with -DWOLFSENTRY_NO_SEM_BUILTIN, and supply semaphore implementation with struct wolfsentry_host_platform_interface argument to wolfsentry_init(). |
@@ -2847,7 +3042,7 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_lock_shared2mutex_abstimed(struct |
2847 | 3042 | WOLFSENTRY_ERROR_RETURN(SYS_OP_FATAL); |
2848 | 3043 | } |
2849 | 3044 | } |
2850 | | - } else |
| 3045 | + } else |
2851 | 3046 | ret = sem_timedwait(&lock->sem_read2write_waiters, abs_timeout); |
2852 | 3047 |
|
2853 | 3048 | if (ret < 0) { |
@@ -3317,6 +3512,19 @@ static wolfsentry_errcode_t wolfsentry_builtin_get_time(void *context, wolfsentr |
3317 | 3512 | WOLFSENTRY_RETURN_OK; |
3318 | 3513 | } |
3319 | 3514 |
|
| 3515 | +#elif defined(THREADX) |
| 3516 | + |
| 3517 | +static wolfsentry_errcode_t wolfsentry_builtin_get_time(void *context, wolfsentry_time_t *now) { |
| 3518 | + struct timespec ts; |
| 3519 | + uint32_t tick_count; |
| 3520 | + (void)context; |
| 3521 | + tick_count = tx_time_get(); |
| 3522 | + ts.tv_sec = (long)tick_count / TX_TICK_TIME_MS; |
| 3523 | + ts.tv_nsec = (long)(tick_count % TX_TICK_TIME_MS) * 1000000; |
| 3524 | + *now = ((wolfsentry_time_t)ts.tv_sec * (wolfsentry_time_t)1000000) + ((wolfsentry_time_t)ts.tv_nsec / (wolfsentry_time_t)1000); |
| 3525 | + WOLFSENTRY_RETURN_OK; |
| 3526 | +} |
| 3527 | + |
3320 | 3528 | #else |
3321 | 3529 |
|
3322 | 3530 | #include <time.h> |
@@ -4264,7 +4472,7 @@ WOLFSENTRY_API wolfsentry_errcode_t wolfsentry_base64_decode(const char *src, si |
4264 | 4472 | const char *src_end = src + src_len; |
4265 | 4473 | size_t dest_len = 0; |
4266 | 4474 |
|
4267 | | - if (WOLFSENTRY_BASE64_DECODED_BUFSPC(src, src_len) > *dest_spc) |
| 4475 | + if (WOLFSENTRY_BASE64_DECODED_BUFSPC(src, (int)src_len) > (int)*dest_spc) |
4268 | 4476 | WOLFSENTRY_ERROR_RETURN(BUFFER_TOO_SMALL); |
4269 | 4477 |
|
4270 | 4478 | for (; src < src_end; ++src) { |
|
0 commit comments