summaryrefslogtreecommitdiff
path: root/components/libc/cplusplus/cpp11/gcc/thread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'components/libc/cplusplus/cpp11/gcc/thread.cpp')
-rw-r--r--components/libc/cplusplus/cpp11/gcc/thread.cpp94
1 files changed, 94 insertions, 0 deletions
diff --git a/components/libc/cplusplus/cpp11/gcc/thread.cpp b/components/libc/cplusplus/cpp11/gcc/thread.cpp
new file mode 100644
index 0000000000..3979da0dc4
--- /dev/null
+++ b/components/libc/cplusplus/cpp11/gcc/thread.cpp
@@ -0,0 +1,94 @@
+/*
+ * 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 "thread"
+#include "__utils.h"
+
+
+#define _RT_NPROCS 0
+
+namespace std
+{
+
+ extern "C"
+ {
+ static void* execute_native_thread_routine(void *p)
+ {
+ thread::invoker_base* t = static_cast<thread::invoker_base*>(p);
+ thread::invoker_base_ptr local;
+ local.swap(t->this_ptr); // tranfer the ownership of the invoker into the thread entry
+
+ local->invoke();
+
+ return NULL;
+ }
+ }
+
+ void thread::start_thread(invoker_base_ptr b)
+ {
+ auto raw_ptr = b.get();
+ // transfer the ownership of the invoker to the new thread
+ raw_ptr->this_ptr = std::move(b);
+ int err = pthread_create(&_m_thr.__cpp_thread_t, NULL,
+ &execute_native_thread_routine, raw_ptr);
+
+ if (err)
+ {
+ raw_ptr->this_ptr.reset();
+ throw_system_error(err, "Failed to create a thread");
+ }
+
+ }
+
+ thread::~thread()
+ {
+ if (joinable()) // when either not joined or not detached
+ terminate();
+ }
+
+ void thread::join()
+ {
+ int err = EINVAL;
+
+ if (joinable())
+ err = pthread_join(native_handle(), NULL);
+
+ if (err)
+ {
+ throw_system_error(err, "thread::join failed");
+ }
+
+ _m_thr = id();
+ }
+
+ void thread::detach()
+ {
+ int err = EINVAL;
+
+ if (joinable())
+ err = pthread_detach(native_handle());
+ if (err)
+ {
+ throw_system_error(err, "thread::detach failed");
+ }
+
+ _m_thr = id();
+ }
+
+ // TODO: not yet actually implemented.
+ // The standard states that the returned value should only be considered a hint.
+ unsigned thread::hardware_concurrency() noexcept
+ {
+ int __n = _RT_NPROCS;
+ if (__n < 0)
+ __n = 0;
+ return __n;
+ }
+}