summaryrefslogtreecommitdiff
path: root/components/libc/cplusplus/os/cxx_Thread.cpp
blob: dc444c255bf14f509540a238bd732f18c7bbfdfa (plain)
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 */

#include "cxx_thread.h"

using namespace rtthread;

/** 
 * @brief Thread class constructor with parameters for stack size, priority, tick, and name.
 * @param stack_size Stack size in bytes
 * @param priority Thread priority
 * @param tick Time slice in ticks
 * @param name Thread name
 */
Thread::Thread(rt_uint32_t stack_size,
               rt_uint8_t  priority,
               rt_uint32_t tick,
               const char *name)
    : _entry(RT_NULL), _param(RT_NULL), started(false)
{
    rt_event_init(&_event, name, 0);

    _thread = rt_thread_create(name,
                               (thread_func_t)func,
                               this,
                               stack_size,
                               priority,
                               tick);
}

/** 
 * @brief Thread class constructor with entry function and parameters.
 * @param entry The entry function pointer for the thread.
 * @param p The parameter to pass to the entry function.
 * @param stack_size The size of the thread stack in bytes.
 * @param priority The priority of the thread.
 * @param tick The time slice (tick) for the thread.
 * @param name The name of the thread.
 */
Thread::Thread(void (*entry)(void *p),
               void *p,
               rt_uint32_t stack_size,
               rt_uint8_t  priority,
               rt_uint32_t tick,
               const char *name)
    : _entry(entry), _param(p), started(false)
{
    rt_event_init(&_event, name, 0);

    _thread = rt_thread_create(name,
                               (thread_func_t)func,
                               this,
                               stack_size,
                               priority,
                               tick);
}

/** 
 * @brief Detach the event and delete the thread when the object is destroyed.
 */
Thread::~Thread()
{
    rt_event_detach(&_event);
    rt_thread_delete(_thread);
}

/** 
 * @brief Start the thread execution.
 * @return true if the thread was successfully started.
 */
bool Thread::start()
{
    if (rt_thread_startup(_thread) == RT_EOK)
    {
        started = true;
    }

    return started;
}

/** 
 * @brief Make the thread sleep for a specified duration.
 * @param millisec Duration in milliseconds.
 */
void Thread::sleep(int32_t millisec)
{
    rt_int32_t tick;

    if (millisec < 0)
        tick = 1;
    else
        tick = rt_tick_from_millisecond(millisec);

    rt_thread_delay(tick);
}

/** 
 * @brief Function to run the thread's entry function.
 */
void Thread::func(Thread *pThis)
{
    if (pThis->_entry != RT_NULL)
    {
        pThis->_entry(pThis->_param);
    }
    else
    {
        pThis->run(pThis->_param);
    }

    rt_event_send(&pThis->_event, 1);
}

/** 
 * @brief Default run function that can be overridden by subclasses.
 */
void Thread::run(void *parameter)
{
    /* please overload this method */
}

/** 
 * @brief Wait for the thread to complete with a timeout.
 * @param millisec Timeout in milliseconds.
 * @return RT_EOK if the thread completed within the timeout, error code otherwise.
 */
rt_err_t Thread::wait(int32_t millisec)
{
    return join(millisec);
}

/** 
 * @brief Join the thread with a timeout.
 * @param millisec Timeout in milliseconds.
 * @return RT_EOK if the thread completed within the timeout, error code otherwise.
 */
rt_err_t Thread::join(int32_t millisec)
{
    if (started)
    {
        rt_int32_t tick;
        if (millisec < 0)
            tick = -1;
        else
            tick = rt_tick_from_millisecond(millisec);

        return rt_event_recv(&_event, 1, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, tick, RT_NULL);
    }
    else
    {
        return -RT_ENOSYS;
    }
}