summaryrefslogtreecommitdiff
path: root/components/cplusplus/cpp11/armclang
diff options
context:
space:
mode:
authorguo <[email protected]>2021-09-28 10:36:54 +0800
committerGitHub <[email protected]>2021-09-28 10:36:54 +0800
commit55a302cd092758a44b589d65470a69d9e8ae4ced (patch)
treee60fc53994c426007e9eb4877e5bd123f124ef39 /components/cplusplus/cpp11/armclang
parent00727d6b6db92dc1cf98f028f26fd6168594b905 (diff)
parent00d42ef73cff61ecda7ff006b077a73e1a4ff669 (diff)
Merge branch 'master' into usbh_construct
Diffstat (limited to 'components/cplusplus/cpp11/armclang')
-rw-r--r--components/cplusplus/cpp11/armclang/clock.cpp29
-rw-r--r--components/cplusplus/cpp11/armclang/condvar.cpp178
-rw-r--r--components/cplusplus/cpp11/armclang/miscellaneous.cpp22
-rw-r--r--components/cplusplus/cpp11/armclang/mutex.cpp108
-rw-r--r--components/cplusplus/cpp11/armclang/thread.cpp109
-rw-r--r--components/cplusplus/cpp11/armclang/tpl.h56
6 files changed, 502 insertions, 0 deletions
diff --git a/components/cplusplus/cpp11/armclang/clock.cpp b/components/cplusplus/cpp11/armclang/clock.cpp
new file mode 100644
index 0000000000..137af393b0
--- /dev/null
+++ b/components/cplusplus/cpp11/armclang/clock.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2021-04-27 flybreak the first version.
+ */
+
+#include <arm-tpl.h>
+#include <sys/time.h>
+#include <rtthread.h>
+
+extern "C" int __ARM_TPL_clock_realtime(__ARM_TPL_timespec_t* __ts)
+{
+ unsigned int t = std::time(nullptr);
+ __ts->tv_sec = t;
+ __ts->tv_nsec = 0;
+ return 0;
+}
+
+extern "C" int __ARM_TPL_clock_monotonic(__ARM_TPL_timespec_t* __ts)
+{
+ unsigned int t = rt_tick_get();
+ __ts->tv_sec = t / RT_TICK_PER_SECOND;
+ __ts->tv_nsec = (t %RT_TICK_PER_SECOND) * NANOSECOND_PER_TICK ;
+ return 0;
+}
diff --git a/components/cplusplus/cpp11/armclang/condvar.cpp b/components/cplusplus/cpp11/armclang/condvar.cpp
new file mode 100644
index 0000000000..7943ccee60
--- /dev/null
+++ b/components/cplusplus/cpp11/armclang/condvar.cpp
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2021-04-27 flybreak the first version.
+ */
+
+#include <arm-tpl.h>
+#include "tpl.h"
+#include <new>
+#include <cstdint>
+#include <stdatomic.h>
+
+arm_tpl_cv::arm_tpl_cv()
+{
+ s = rt_sem_create("semxs", 0, RT_IPC_FLAG_PRIO);
+ if (s == nullptr)
+ RT_ASSERT(0);
+ h = rt_sem_create("semxh", 0, RT_IPC_FLAG_PRIO);
+ if (h == nullptr)
+ {
+ rt_sem_delete(s);
+ RT_ASSERT(0);
+ }
+ x = rt_mutex_create("mutx", RT_IPC_FLAG_PRIO);
+ if (x == nullptr)
+ {
+ rt_sem_delete(s);
+ rt_sem_delete(h);
+ RT_ASSERT(0);
+ }
+}
+
+arm_tpl_cv::~arm_tpl_cv()
+{
+ rt_mutex_delete(x);
+ rt_sem_delete(h);
+ rt_sem_delete(s);
+}
+
+void arm_tpl_cv::wait(rt_mutex_t lock, bool recursive)
+{
+ while (rt_mutex_take(x, ARM_TPL_MAX_DELAY) != 0);
+ rt_sem_release(s);
+ rt_mutex_release(x);
+ if (recursive)
+ rt_mutex_release(lock);
+ else
+ rt_mutex_release(lock);
+ while (rt_sem_take(h, ARM_TPL_MAX_DELAY) != 0);
+ if (recursive)
+ while (rt_mutex_take(lock, ARM_TPL_MAX_DELAY) != 0);
+ else
+ while (rt_mutex_take(lock, ARM_TPL_MAX_DELAY) != 0);
+}
+
+int arm_tpl_cv::timedwait(rt_mutex_t lock, bool recursive, unsigned int timeout_ms)
+{
+ int result = 0;
+ while (rt_mutex_take(x, ARM_TPL_MAX_DELAY) != 0);
+ rt_sem_release(s);
+ rt_mutex_release(x);
+ if (recursive)
+ rt_mutex_release(lock);
+ else
+ rt_mutex_release(lock);
+ if (rt_sem_take(h, rt_tick_from_millisecond(timeout_ms)) != 0)
+ {
+ while (rt_mutex_take(x, ARM_TPL_MAX_DELAY) != 0);
+ if (rt_sem_take(h, 0) != 0)
+ {
+ if (rt_sem_take(s, 0) != 0)
+ result = -1;
+ else
+ result = 1;
+ }
+ rt_mutex_release(x);
+ }
+ if (recursive)
+ while (rt_mutex_take(lock, ARM_TPL_MAX_DELAY) != 0);
+ else
+ while (rt_mutex_take(lock, ARM_TPL_MAX_DELAY) != 0);
+ return result;
+}
+
+void arm_tpl_cv::signal()
+{
+ while (rt_mutex_take(x, ARM_TPL_MAX_DELAY) != 0);
+ if (rt_sem_take(s, 0) == 0)
+ rt_sem_release(h);
+ rt_mutex_release(x);
+}
+
+void arm_tpl_cv::broadcast()
+{
+ while (rt_mutex_take(x, ARM_TPL_MAX_DELAY) != 0);
+ auto count = s->value;
+ for (auto i = 0; i < count; i++)
+ {
+ while (rt_sem_take(s, ARM_TPL_MAX_DELAY) != 0);
+ rt_sem_release(h);
+ }
+ rt_mutex_release(x);
+}
+
+static int check_create(volatile __ARM_TPL_condvar_t *__vcv)
+{
+ if (__vcv->data == 0)
+ {
+ uintptr_t cv_new;
+ cv_new = reinterpret_cast<uintptr_t>(new arm_tpl_cv());
+ if (cv_new == 0)
+ {
+ return -1;
+ }
+ uintptr_t cv_null = 0;
+ if (!atomic_compare_exchange_strong(&__vcv->data, &cv_null, cv_new))
+ delete reinterpret_cast<arm_tpl_cv *>(cv_new);
+ }
+ return 0;
+}
+
+extern "C" int __ARM_TPL_condvar_wait(__ARM_TPL_condvar_t *__cv, __ARM_TPL_mutex_t *__m)
+{
+ volatile __ARM_TPL_condvar_t *__vcv = __cv;
+ if (check_create(__vcv) != 0)
+ return -1;
+ struct arm_tpl_mutex_struct *tmutex = (struct arm_tpl_mutex_struct *)(__m->data);
+ ((arm_tpl_cv *) __vcv->data)->wait(tmutex->mutex, tmutex->type == RECURSIVE);
+ return 0;
+}
+
+extern "C" int __ARM_TPL_condvar_timedwait(__ARM_TPL_condvar_t *__cv,
+ __ARM_TPL_mutex_t *__m,
+ __ARM_TPL_timespec_t *__ts)
+{
+ volatile __ARM_TPL_condvar_t *__vcv = __cv;
+ if (check_create(__vcv) != 0)
+ return -1;
+ __ARM_TPL_timespec_t now;
+ if (__ARM_TPL_clock_realtime(&now) != 0)
+ return -1;
+ struct arm_tpl_mutex_struct *tmutex = (struct arm_tpl_mutex_struct *)(__m->data);
+ unsigned int timeout_ms = (__ts->tv_sec - now.tv_sec) * 1000 + (__ts->tv_nsec - now.tv_nsec) / 1000000;
+ if (((arm_tpl_cv *) __vcv->data)->timedwait(tmutex->mutex, tmutex->type == RECURSIVE, timeout_ms) < 0)
+ return -1;
+ return 0;
+}
+
+extern "C" int __ARM_TPL_condvar_signal(__ARM_TPL_condvar_t *__cv)
+{
+ volatile __ARM_TPL_condvar_t *__vcv = __cv;
+ if (__vcv->data != 0)
+ ((arm_tpl_cv *) __vcv->data)->signal();
+ return 0;
+}
+
+extern "C" int __ARM_TPL_condvar_broadcast(__ARM_TPL_condvar_t *__cv)
+{
+ volatile __ARM_TPL_condvar_t *__vcv = __cv;
+ if (__vcv->data != 0)
+ ((arm_tpl_cv *) __vcv->data)->broadcast();
+ return 0;
+}
+
+extern "C" int __ARM_TPL_condvar_destroy(__ARM_TPL_condvar_t *__cv)
+{
+ volatile __ARM_TPL_condvar_t *__vcv = __cv;
+ if (__vcv->data != 0)
+ {
+ delete (arm_tpl_cv *) __vcv->data;
+ __vcv->data = 0;
+ }
+ return 0;
+}
diff --git a/components/cplusplus/cpp11/armclang/miscellaneous.cpp b/components/cplusplus/cpp11/armclang/miscellaneous.cpp
new file mode 100644
index 0000000000..a084eda8c8
--- /dev/null
+++ b/components/cplusplus/cpp11/armclang/miscellaneous.cpp
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2021-04-27 flybreak the first version.
+ */
+
+#include <arm-tpl.h>
+
+extern "C" int __ARM_TPL_execute_once(__ARM_TPL_exec_once_flag *__flag,
+ void (*__init_routine)(void))
+{
+ if (*__flag == 0)
+ {
+ __init_routine();
+ *__flag = 1;
+ }
+ return 0;
+}
diff --git a/components/cplusplus/cpp11/armclang/mutex.cpp b/components/cplusplus/cpp11/armclang/mutex.cpp
new file mode 100644
index 0000000000..44a70efcf7
--- /dev/null
+++ b/components/cplusplus/cpp11/armclang/mutex.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2021-04-27 flybreak the first version.
+ */
+
+#include <arm-tpl.h>
+#include <cstdint>
+#include <stdatomic.h>
+#include "tpl.h"
+
+static int check_create(volatile __ARM_TPL_mutex_t *__vm, bool recursive = false)
+{
+ if (__vm->data == 0)
+ {
+ uintptr_t mut_null = 0;
+ arm_tpl_mutex_struct *mutex_p = (arm_tpl_mutex_struct *)rt_malloc(sizeof(arm_tpl_mutex_struct));
+ if (mutex_p == nullptr) return -1;
+
+ if (recursive)
+ mutex_p->mutex = rt_mutex_create("mutexx", RT_IPC_FLAG_PRIO);
+ else
+ mutex_p->mutex = rt_mutex_create("mutexx", RT_IPC_FLAG_PRIO);
+
+ if (mutex_p->mutex == nullptr)
+ {
+ rt_free(mutex_p);
+ return -1;
+ }
+ mutex_p->type = recursive ? RECURSIVE : NORMAL;
+ uintptr_t mut_new = reinterpret_cast<uintptr_t>(mutex_p);
+ if (!atomic_compare_exchange_strong(&__vm->data, &mut_null, mut_new))
+ {
+ rt_mutex_delete(mutex_p->mutex);
+ rt_free(mutex_p);
+ }
+ }
+ return 0;
+}
+
+static int mutexLock(arm_tpl_mutex_struct *mutex_p, rt_tick_t timeOut)
+{
+ if (mutex_p->type == RECURSIVE)
+ {
+ if (rt_mutex_take(mutex_p->mutex, timeOut) == 0)
+ return 0;
+ }
+ else
+ {
+ if (rt_mutex_take(mutex_p->mutex, timeOut) == 0)
+ return 0;
+ }
+ return -1;
+}
+
+static int mutexUnlock(arm_tpl_mutex_struct *mutex_p)
+{
+ if (mutex_p->type == RECURSIVE)
+ rt_mutex_release(mutex_p->mutex);
+ else
+ rt_mutex_release(mutex_p->mutex);
+ return 0;
+}
+
+extern "C" int __ARM_TPL_recursive_mutex_init(__ARM_TPL_mutex_t *__m)
+{
+ volatile __ARM_TPL_mutex_t *__vm = __m;
+ return check_create(__vm, true);
+}
+
+extern "C" int __ARM_TPL_mutex_lock(__ARM_TPL_mutex_t *__m)
+{
+ volatile __ARM_TPL_mutex_t *__vm = __m;
+ if (check_create(__vm))
+ return -1;
+ while (mutexLock((arm_tpl_mutex_struct *)(__vm->data), ARM_TPL_MAX_DELAY) != 0);
+ return 0;
+}
+
+extern "C" int __ARM_TPL_mutex_trylock(__ARM_TPL_mutex_t *__m)
+{
+ volatile __ARM_TPL_mutex_t *__vm = __m;
+ if (check_create(__vm))
+ return -1;
+ return mutexLock((arm_tpl_mutex_struct *)(__vm->data), 0);
+}
+
+extern "C" int __ARM_TPL_mutex_unlock(__ARM_TPL_mutex_t *__m)
+{
+ volatile __ARM_TPL_mutex_t *__vm = __m;
+ return mutexUnlock((arm_tpl_mutex_struct *)(__vm->data));
+}
+
+extern "C" int __ARM_TPL_mutex_destroy(__ARM_TPL_mutex_t *__m)
+{
+ volatile __ARM_TPL_mutex_t *__vm = __m;
+ if (__vm->data != 0)
+ {
+ rt_mutex_delete(((arm_tpl_mutex_struct *)(__vm->data))->mutex);
+ rt_free((void *)(__vm->data));
+ __vm->data = 0;
+ }
+ return 0;
+}
diff --git a/components/cplusplus/cpp11/armclang/thread.cpp b/components/cplusplus/cpp11/armclang/thread.cpp
new file mode 100644
index 0000000000..f7f0cb4077
--- /dev/null
+++ b/components/cplusplus/cpp11/armclang/thread.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2021-04-27 flybreak the first version.
+ */
+
+#include <arm-tpl.h>
+#include "tpl.h"
+#include <cstdio>
+#include <pthread.h>
+
+extern "C" int __ARM_TPL_thread_create(__ARM_TPL_thread_t *__t,
+ void *(*__func)(void *),
+ void *__arg)
+{
+ int ret = 0;
+ /* TODO memory leek */
+ pthread_t *pid = (pthread_t *)rt_malloc(sizeof(pthread_t));
+ if (pid == nullptr)
+ return -1;
+ ret = pthread_create(pid, RT_NULL, __func, __arg);
+ if (ret == 0)
+ {
+ __t->data = (std::uintptr_t)pid;
+ return 0;
+ }
+ return -1;
+}
+
+extern "C" int __ARM_TPL_thread_id_compare(__ARM_TPL_thread_id __tid1,
+ __ARM_TPL_thread_id __tid2)
+{
+ if (__tid1 > __tid2)
+ return 1;
+ else if (__tid1 < __tid2)
+ return -1;
+ else
+ return 0;
+}
+
+extern "C" __ARM_TPL_thread_id __ARM_TPL_thread_get_current_id()
+{
+ return (__ARM_TPL_thread_id)pthread_self();
+}
+
+extern "C" __ARM_TPL_thread_id __ARM_TPL_thread_get_id(
+ const __ARM_TPL_thread_t *__t)
+{
+ return (__ARM_TPL_thread_id)((*(pthread_t *)__t->data));
+}
+
+extern "C" int __ARM_TPL_thread_join(__ARM_TPL_thread_t *__t)
+{
+ pthread_join((*(pthread_t *)__t->data), RT_NULL);
+ return 0;
+}
+
+extern "C" int __ARM_TPL_thread_detach(__ARM_TPL_thread_t *__t)
+{
+ pthread_detach((*(pthread_t *)__t->data));
+ return 0;
+}
+
+extern "C" void __ARM_TPL_thread_yield()
+{
+ rt_thread_yield();
+}
+
+extern "C" int __ARM_TPL_thread_nanosleep(const __ARM_TPL_timespec_t *__req,
+ __ARM_TPL_timespec_t *__rem)
+{
+ return nanosleep(__req, rem);
+}
+
+extern "C" unsigned __ARM_TPL_thread_hw_concurrency()
+{
+ return 1;
+}
+
+extern "C" int __ARM_TPL_tls_create(__ARM_TPL_tls_key *__key,
+ void (*__at_exit)(void *))
+{
+ pthread_key_t key;
+
+ if (pthread_key_create(&key, __at_exit) == 0)
+ {
+ *__key = key;
+ return 0;
+ }
+ return -1;
+}
+
+extern "C" void *__ARM_TPL_tls_get(__ARM_TPL_tls_key __key)
+{
+ return pthread_getspecific(__key);
+}
+
+extern "C" int __ARM_TPL_tls_set(__ARM_TPL_tls_key __key, void *__p)
+{
+ if (pthread_setspecific(__key, (void*)__p) != 0)
+ {
+ return -1;
+ }
+ return 0;
+}
diff --git a/components/cplusplus/cpp11/armclang/tpl.h b/components/cplusplus/cpp11/armclang/tpl.h
new file mode 100644
index 0000000000..70c9503cec
--- /dev/null
+++ b/components/cplusplus/cpp11/armclang/tpl.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2021-04-27 flybreak the first version.
+ */
+
+#pragma once
+#ifndef __cplusplus
+void ARMTPLInit();
+#else
+#include <rtthread.h>
+
+#define ARM_TPL_MAX_DELAY 1000
+#define ARM_TPL_THREAD_STACK_SIZE 4096
+
+enum arm_tpl_mutex_type
+{
+ NORMAL,
+ RECURSIVE,
+};
+
+struct arm_tpl_mutex_struct
+{
+ rt_mutex_t mutex;
+ arm_tpl_mutex_type type;
+};
+
+struct arm_tpl_thread_struct
+{
+ rt_thread_t task;
+ void *(*func)(void *);
+ void *arg;
+ rt_sem_t join_sem;
+ rt_sem_t detach_sem;
+};
+
+class arm_tpl_cv
+{
+public:
+ arm_tpl_cv();
+ ~arm_tpl_cv();
+ void wait(rt_mutex_t lock, bool recursive);
+ int timedwait(rt_mutex_t lock, bool recursive, unsigned int timeout_ms);
+ void signal();
+ void broadcast();
+private:
+ rt_sem_t s;
+ rt_sem_t h;
+ rt_mutex_t x;
+};
+
+#endif