Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions components/libc/cplusplus/os/cxx_Semaphore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,45 @@

using namespace rtthread;

/**
* @brief Semaphore class implementation.
*/
Semaphore::Semaphore(const char *name, int32_t count)
{
// Initialize the semaphore with a specified count and FIFO order.
rt_sem_init(&mID, name, count, RT_IPC_FLAG_FIFO);
}

/**
* @brief Wait on the semaphore.
* @param millisec Timeout in milliseconds.
* @return Boolean indicating if the semaphore was successfully taken.
*/
bool Semaphore::wait(int32_t millisec)
{
rt_int32_t tick;

// Convert milliseconds to system ticks.
if (millisec < 0)
tick = -1;
else
tick = rt_tick_from_millisecond(millisec);

// Attempt to take the semaphore.
return rt_sem_take(&mID, tick) == RT_EOK;
}

/**
* @brief Release the semaphore.
*/
void Semaphore::release(void)
{
rt_sem_release(&mID);
}

/**
* Detach the semaphore when the object is destroyed.
*/
Semaphore::~Semaphore()
{
rt_sem_detach(&mID);
Expand Down
51 changes: 45 additions & 6 deletions components/libc/cplusplus/os/cxx_Thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@

using namespace rtthread;

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

Expand All @@ -27,13 +30,16 @@ Thread::Thread(rt_uint32_t stack_size,
tick);
}

/**
* @brief Thread class constructor with entry function and parameters.
*/
Thread::Thread(void (*entry)(void *p),
void *p,
rt_uint32_t stack_size,
rt_uint8_t priority,
rt_uint8_t priority,
rt_uint32_t tick,
const char *name)
: _entry(entry), _param(p), started(false)
const char *name) :
_entry(entry), _param(p), started(false)
{
rt_event_init(&_event, name, 0);

Expand All @@ -45,12 +51,19 @@ Thread::Thread(void (*entry)(void *p),
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 Boolean indicating if the thread was successfully started.
*/
bool Thread::start()
{
if (rt_thread_startup(_thread) == RT_EOK)
Expand All @@ -61,20 +74,30 @@ bool Thread::start()
return started;
}

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

// Convert milliseconds to system ticks.
if (millisec < 0)
tick = 1;
else
tick = rt_tick_from_millisecond(millisec);

// Delay the thread for a specified number of ticks.
rt_thread_delay(tick);
}

/**
* Static function to run the thread's entry function.
*/
void Thread::func(Thread *pThis)
{
// If an entry function is provided, execute it.
if (pThis->_entry != RT_NULL)
{
pThis->_entry(pThis->_param);
Expand All @@ -84,30 +107,46 @@ void Thread::func(Thread *pThis)
pThis->run(pThis->_param);
}

// Send an event to signal thread completion.
rt_event_send(&pThis->_event, 1);
}

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

/**
* Wait for the thread to complete with a timeout.
* @param millisec Timeout in milliseconds.
* @return Status code indicating the execution status.
*/
rt_err_t Thread::wait(int32_t millisec)
{
return join(millisec);
}

/**
* Join the thread with a timeout.
* @param millisec Timeout in milliseconds.
* @return Status code indicating the execution status.
*/
rt_err_t Thread::join(int32_t millisec)
{
if (started)
{
rt_int32_t tick;

// Convert milliseconds to system ticks.
if (millisec < 0)
tick = -1;
else
tick = rt_tick_from_millisecond(millisec);

// Wait for the thread's completion event.
return rt_event_recv(&_event, 1, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, tick, RT_NULL);
}
else
Expand Down
27 changes: 14 additions & 13 deletions components/libc/cplusplus/utest/tc_atomic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
*/
static void test_atomic_load_store_int32(void)
{
constexpr int kRound = 10000000;
constexpr int kRound = 10000000;
std::atomic<int32_t> thread_count(0);
std::atomic<int32_t> count(100);
uassert_int_equal(count.load(), 100);
Expand Down Expand Up @@ -56,7 +56,7 @@ static void test_atomic_load_store_int32(void)
*/
static void test_atomic_load_store_int64(void)
{
constexpr int kRound = 10000000;
constexpr int kRound = 10000000;
std::atomic<int64_t> thread_count(0);
std::atomic<int64_t> count(100);
uassert_int_equal(count.load(), 100);
Expand Down Expand Up @@ -121,9 +121,9 @@ static void test_atomic_basic_int32(void)
val.exchange(1);
uassert_int_equal(val.load(), 1);

int32_t x = 2;
int32_t y = 3;
bool exchanged = val.compare_exchange_strong(x, y);
int32_t x = 2;
int32_t y = 3;
bool exchanged = val.compare_exchange_strong(x, y);
uassert_false(exchanged);
uassert_int_equal(val.load(), 1);
uassert_int_equal(x, 1);
Expand Down Expand Up @@ -168,9 +168,9 @@ static void test_atomic_basic_int64(void)
val.exchange(1);
uassert_int_equal(val.load(), 1);

int64_t x = 2;
int64_t y = 3;
bool exchanged = val.compare_exchange_strong(x, y);
int64_t x = 2;
int64_t y = 3;
bool exchanged = val.compare_exchange_strong(x, y);
uassert_false(exchanged);
uassert_int_equal(val.load(), 1);
uassert_int_equal(x, 1);
Expand All @@ -191,7 +191,7 @@ static void test_atomic_bool(void)
flag.exchange(false);
uassert_false(flag.load());
bool expected = false;
bool desired = true;
bool desired = true;
uassert_true(flag.compare_exchange_strong(expected, desired));
uassert_true(flag.load());
}
Expand All @@ -201,7 +201,7 @@ static void test_atomic_bool(void)
*/
static void test_atomic_pointer(void)
{
int a = 1, b = 2;
int a = 1, b = 2;
std::atomic<int *> ptr(&a);
ptr.store(&b);
uassert_int_equal(*ptr.load(), 2);
Expand Down Expand Up @@ -230,20 +230,21 @@ static void test_memory_order(void)
static void test_compare_exchange_weak(void)
{
std::atomic<int> val(1);
int expected = 1;
int desired = 2;
int expected = 1;
int desired = 2;
while (!val.compare_exchange_weak(expected, desired))
{
expected = 1; // reset
}
uassert_int_equal(val.load(), 2);
}

// Test case initialization function.
static rt_err_t utest_tc_init(void)
{
return RT_EOK;
}

// Test case cleanup function.
static rt_err_t utest_tc_cleanup(void)
{
return RT_EOK;
Expand Down
6 changes: 6 additions & 0 deletions components/libc/cplusplus/utest/tc_smartptr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,16 @@ static void test_shared_ptr(void)
uassert_int_equal(p1.use_count(), 2);
}

/**
* @brief Test case initialization function.
*/
static rt_err_t utest_tc_init(void)
{
return RT_EOK;
}
/**
* @brief Test case cleanup function.
*/

static rt_err_t utest_tc_cleanup(void)
{
Expand Down
40 changes: 31 additions & 9 deletions components/libc/cplusplus/utest/tc_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,48 +12,70 @@
#include "utest.h"
#include <thread>


/**
* @brief Function to test thread functionality.
*/
static void test_thread(void)
{
int count = 0;
auto func = [&]() mutable
{
int count = 0; // Initialize a counter to zero.

// Lambda function to increment the count.
auto func = [&]() mutable {
for (int i = 0; i < 100; ++i)
{
++count;
++count; // Increment the count 100 times.
}
};

// Create and run a thread executing the lambda function.
std::thread t1(func);
t1.join();
t1.join(); // Wait for the thread to finish execution.

// Verify if the count is as expected after the first thread execution.
if (count != 100)
{
uassert_false(1);
uassert_false(1); // Assert failure if count is not 100.
}

// Create and run another thread executing the same lambda function.
std::thread t2(func);
t2.join();
t2.join(); // Wait for the second thread to finish execution.

// Verify if the count is as expected after the second thread execution.
if (count != 200)
{
uassert_false(1);
uassert_false(1); // Assert failure if count is not 200.
}

// If both assertions passed, the test is successful.
uassert_true(1);
}


/**
* @brief Test case initialization function.
*/

static rt_err_t utest_tc_init(void)
{
return RT_EOK;
}

/**
* @brief Test case cleanup function.
*/
static rt_err_t utest_tc_cleanup(void)
{
return RT_EOK;
}

/**
* @brief Main test case function that runs the test.
*/
static void testcase(void)
{
UTEST_UNIT_RUN(test_thread);
}

// Export the test case with initialization and cleanup functions and a timeout of 10 ticks.
UTEST_TC_EXPORT(testcase, "components.libc.cpp.thread_tc", utest_tc_init, utest_tc_cleanup, 10);