thread.cpp
2.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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;
}
}