Motion_EC_HC32_archived/rt-thread/components/cplusplus/cpp11/gcc/thread.cpp

95 lines
2.1 KiB
C++
Raw Normal View History

2022-01-10 16:20:39 +08:00
/*
* 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
2022-01-10 17:10:14 +08:00
raw_ptr->this_ptr = std::move(b);
2022-01-10 16:20:39 +08:00
int err = pthread_create(&_m_thr.__cpp_thread_t, NULL,
&execute_native_thread_routine, raw_ptr);
2022-01-10 17:10:14 +08:00
if (err)
2022-01-10 16:20:39 +08:00
{
raw_ptr->this_ptr.reset();
throw_system_error(err, "Failed to create a thread");
}
2022-01-10 17:10:14 +08:00
}
2022-01-10 16:20:39 +08:00
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);
2022-01-10 17:10:14 +08:00
if (err)
2022-01-10 16:20:39 +08:00
{
throw_system_error(err, "thread::join failed");
}
2022-01-10 17:10:14 +08:00
2022-01-10 16:20:39 +08:00
_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");
}
2022-01-10 17:10:14 +08:00
2022-01-10 16:20:39 +08:00
_m_thr = id();
}
// TODO: not yet actually implemented.
// The standard states that the returned value should only be considered a hint.
2022-01-10 17:10:14 +08:00
unsigned thread::hardware_concurrency() noexcept
{
2022-01-10 16:20:39 +08:00
int __n = _RT_NPROCS;
if (__n < 0)
__n = 0;
return __n;
}
}