From 993e878926f671cc408d6079126c173f2b63c87f Mon Sep 17 00:00:00 2001 From: tzhu Date: Fri, 15 Mar 2024 21:45:49 +0800 Subject: [PATCH] add subfunction --- .github/workflows/c-cpp.yml | 5 +- .gitignore | 2 +- bash_build.sh | 2 +- pt-os.cpp | 110 +++++++++++++++++++--------------- pt-os.h | 33 ++++++---- pt-osConfig.h | 5 +- tests/1p1c.cpp | 14 ++--- tests/1p2c.cpp | 16 ++--- tests/2p1c.cpp | 20 +++---- tests/main.cpp | 14 ++--- tests/os_test.h | 15 +++++ tests/resume.cpp | 41 ++++++------- tests/subfunction.cpp | 116 ++++++++++++++++++++++++++++++++++++ tests/test.h | 8 --- 14 files changed, 264 insertions(+), 137 deletions(-) create mode 100644 tests/os_test.h create mode 100644 tests/subfunction.cpp delete mode 100644 tests/test.h diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 0a85585..ca9f893 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -17,4 +17,7 @@ jobs: - name: build with bash run: bash bash_build.sh - name: run tests - run: pushd build && ./test_pt_os &&popd + run: | + pushd build + ./test_pt_os + popd diff --git a/.gitignore b/.gitignore index 6f65c48..567609b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -./build +build/ diff --git a/bash_build.sh b/bash_build.sh index 7022df6..4429194 100644 --- a/bash_build.sh +++ b/bash_build.sh @@ -25,7 +25,7 @@ git clone https://github.com/ZhuLingQing/protothreads.git g++ -g -o ${lib_name}.o -c ../pt-os.cpp -I./protothreads ar -rv lib${lib_name}.a ${lib_name}.o #build the test -g++ -g -o test_pt_os ../tests/*.cpp -I./protothreads -I.. -L. -l${lib_name} +g++ -g -o test_pt_os ../tests/*.cpp -I./protothreads -I.. -I../tests -L. -l${lib_name} #run the test ./test_pt_os rc=$? diff --git a/pt-os.cpp b/pt-os.cpp index b204fd8..33f68c5 100644 --- a/pt-os.cpp +++ b/pt-os.cpp @@ -3,7 +3,7 @@ static inline size_t min_(size_t a, size_t b) { return a < b ? a : b; } -#define OsTaskId2Idx(id) (int)(id - kPt_) +#define OsTaskId2Idx(id) (int)(id - kPt_) class TaskControlBlock { @@ -12,38 +12,45 @@ class TaskControlBlock void Reset() { - #if defined(osMaxNameLen) && osMaxNameLen > 0 - memset(kName_, 0, sizeof(kName_)); - #endif +#if defined(osMaxNameLen) && osMaxNameLen > 0 + memset(kName_, 0, sizeof(kName_)); +#endif kTask_ = nullptr; kPtStatus_ = OsTaskNotExist; } void Register(const char *name, TaskFunction task, void *param) { - #if defined(osMaxNameLen) && osMaxNameLen > 0 - memcpy(kName_, name, min_(sizeof(kName_) - 1, strlen(name))); - #endif +#if defined(osMaxNameLen) && osMaxNameLen > 0 + memcpy(kName_, name, min_(sizeof(kName_) - 1, strlen(name))); +#endif kTask_ = task; kParam_ = param; kEntered_ = false; kPtStatus_ = OsTaskWaiting; } - - bool Yield(OsTaskId taskId) + + bool Schedule(OsTaskId taskId) { + OsTaskStatus newStatus; if (kPtStatus_ == OsTaskExit) return false; if (!kEntered_ && kPtStatus_ != OsTaskSuspend) { kEntered_ = true; - kPtStatus_ = (OsTaskStatus)kTask_(taskId, kParam_); + newStatus = (OsTaskStatus)kTask_(taskId, kParam_); kEntered_ = false; + if (kPtStatus_ < OsTaskSuspend) + { + kPtStatus_ = newStatus; + return (kPtStatus_ == OsTaskExit) ? true : false; + } + return false; } - return (kPtStatus_ == OsTaskExit)?true:false; + return (kPtStatus_ == OsTaskExit) ? true : false; } - + OsTaskStatus Status() { return kPtStatus_; } - int Suspend() + int Suspend() { if (kPtStatus_ == OsTaskNotExist) return INVALID_TASK_ID; if (kPtStatus_ == OsTaskExit) return INVALID_TASK_STATUS; @@ -58,7 +65,7 @@ class TaskControlBlock return TASK_OP_SUCCESS; } - int Delete() + int Delete() { if (kPtStatus_ == OsTaskNotExist) return INVALID_TASK_ID; if (kPtStatus_ == OsTaskExit) return INVALID_TASK_STATUS; @@ -68,18 +75,18 @@ class TaskControlBlock const char *Name() { - #if defined(osMaxNameLen) && osMaxNameLen > 0 - return kName_; - #else - return nullptr; - #endif +#if defined(osMaxNameLen) && osMaxNameLen > 0 + return kName_; +#else + return "N/A"; +#endif } protected: TaskFunction kTask_; - #if defined(osMaxNameLen) && osMaxNameLen > 0 +#if defined(osMaxNameLen) && osMaxNameLen > 0 char kName_[osMaxNameLen]; - #endif +#endif void *kParam_; bool kEntered_; OsTaskStatus kPtStatus_; @@ -100,22 +107,25 @@ class PtOs return &kPt_[kIdx_ - 1]; } - void Yield() + void Schedule() { for (int i = 0; i < kIdx_; i++) { - if (true == kTaskCb_[i].Yield(kPt_ + i)) kNumLiveTasks_--; + kCurrentTaskId_ = kPt_ + i; + if (true == kTaskCb_[i].Schedule(kPt_ + i)) kNumLiveTasks_--; } } const char *Name(OsTaskId taskId) { + if (taskId == OsSelfId) taskId = kCurrentTaskId_; OS_ASSERT((taskId >= &kPt_[0] && taskId < &kPt_[osMaxThreads])); return kTaskCb_[OsTaskId2Idx(taskId)].Name(); } int Delete(OsTaskId taskId) { + if (taskId == OsSelfId) taskId = kCurrentTaskId_; OS_ASSERT((taskId >= &kPt_[0] && taskId < &kPt_[osMaxThreads])); auto rc = kTaskCb_[OsTaskId2Idx(taskId)].Delete(); if (rc == TASK_OP_SUCCESS) kNumLiveTasks_--; @@ -124,83 +134,85 @@ class PtOs int Suspend(OsTaskId taskId) { + if (taskId == OsSelfId) taskId = kCurrentTaskId_; OS_ASSERT((taskId >= &kPt_[0] && taskId < &kPt_[osMaxThreads])); return kTaskCb_[OsTaskId2Idx(taskId)].Suspend(); } int Resume(OsTaskId taskId) { + if (taskId == OsSelfId) taskId = kCurrentTaskId_; OS_ASSERT((taskId >= &kPt_[0] && taskId < &kPt_[osMaxThreads])); return kTaskCb_[OsTaskId2Idx(taskId)].Resume(); } OsTaskStatus Status(OsTaskId taskId) { + if (taskId == OsSelfId) taskId = kCurrentTaskId_; OS_ASSERT((taskId >= &kPt_[0] && taskId < &kPt_[osMaxThreads])); return kTaskCb_[OsTaskId2Idx(taskId)].Status(); } - int NumLiveTasks() { return kNumLiveTasks_; } + int NumOfLivingTasks() { return kNumLiveTasks_; } void Reset() { - for (int i = 0; i < osMaxThreads; i++) - kTaskCb_[i].Reset(); + for (int i = 0; i < osMaxThreads; i++) kTaskCb_[i].Reset(); kIdx_ = 0; kNumLiveTasks_ = 0; } + OsTaskId CurrentTaskId() { return kCurrentTaskId_; } + protected: TaskControlBlock kTaskCb_[osMaxThreads]; struct pt kPt_[osMaxThreads]; int kIdx_; int kNumLiveTasks_; + OsTaskId kCurrentTaskId_; }; static PtOs sOsControlBlock_; -OsTaskId RegisterTask(const char *name, TaskFunction task, void *param) { return sOsControlBlock_.RegisterTask(name, task, param); } - -// Cause Registered Service get scheduled -void TaskYield(void) +OsTaskId RegisterTask(const char *name, TaskFunction task, void *param) { - sOsControlBlock_.Yield(); + return sOsControlBlock_.RegisterTask(name, task, param); } -const char *TaskName(OsTaskId taskId) -{ - return sOsControlBlock_.Name(taskId); -} +void TaskYield(void) { sOsControlBlock_.Schedule(); } + +const char *TaskName(OsTaskId taskId) { return sOsControlBlock_.Name(taskId); } int TaskDelete(OsTaskId taskId) { + if (sOsControlBlock_.CurrentTaskId() == taskId) return INVALID_TASK_ID; return sOsControlBlock_.Delete(taskId); } int TaskSuspend(OsTaskId taskId) { - return sOsControlBlock_.Suspend(taskId); + int rc = sOsControlBlock_.Suspend(taskId); + if (rc != TASK_OP_SUCCESS) return rc; + if (sOsControlBlock_.CurrentTaskId() == taskId) + { + while (TaskStatus(taskId) == OsTaskSuspend) sOsControlBlock_.Schedule(); + } + return TASK_OP_SUCCESS; } -int TaskResume(OsTaskId taskId) -{ - return sOsControlBlock_.Resume(taskId); -} +int TaskResume(OsTaskId taskId) { return sOsControlBlock_.Resume(taskId); } -OsTaskStatus TaskStatus(OsTaskId taskId) -{ - return sOsControlBlock_.Status(taskId); -} +OsTaskStatus TaskStatus(OsTaskId taskId) { return sOsControlBlock_.Status(taskId); } -void OsInit(void) +int OsInit(void) { - //make sure - OS_ASSERT(0 == sOsControlBlock_.NumLiveTasks()); + // make sure all tasks are released + OS_ASSERT(0 == sOsControlBlock_.NumOfLivingTasks()); sOsControlBlock_.Reset(); + return TASK_OP_SUCCESS; } void OsStart(void) { - while (sOsControlBlock_.NumLiveTasks() > 0) - sOsControlBlock_.Yield(); + while (sOsControlBlock_.NumOfLivingTasks() > 0) sOsControlBlock_.Schedule(); } \ No newline at end of file diff --git a/pt-os.h b/pt-os.h index f09f90c..8cef01b 100644 --- a/pt-os.h +++ b/pt-os.h @@ -1,28 +1,34 @@ #ifndef _PT_OS_H_ #define _PT_OS_H_ -#include "pt-osConfig.h" #include +#include "pt-osConfig.h" #define TASK_BEGIN(id) PT_BEGIN(id) #define TASK_YIELD(id) PT_YIELD(id) -#define TASK_WAIT_UNTIL(id,cond) PT_WAIT_UNTIL(id, cond) -#define TASK_SUSPEND(id) do { if (taskId == id) PT_EXIT(id); else TaskSuspend(id); } while(0) -#define TASK_DELETE(id) do { if (taskId == id) PT_END(id); else TaskDelete(id); } while(0) +#define TASK_WAIT_UNTIL(id, cond) PT_WAIT_UNTIL(id, cond) #define TASK_EXIT(id) return PT_ENDED #define TASK_END(id) PT_END(id) #define TASK_DECLARE(thread_declare) PT_THREAD(thread_declare) +#define TaskWaitUntil(cond) \ + do \ + { \ + while (!(cond)) TaskYield(); \ + } while (0) + #if __cplusplus extern "C" { #endif - typedef struct pt * OsTaskId; - #define OsInvlidTaskId ((OsTaskId)INVALID_TASK_ID) + typedef struct pt *OsTaskId; +#define OsInvlidTaskId ((OsTaskId)INVALID_TASK_ID) +#define OsSelfId ((OsTaskId)0) - #define TASK_OP_SUCCESS (0) - #define INVALID_TASK_ID (-1) - #define INVALID_TASK_STATUS (-2) +// return enumerations +#define TASK_OP_SUCCESS (0) +#define INVALID_TASK_ID (-1) +#define INVALID_TASK_STATUS (-2) typedef enum { @@ -31,7 +37,7 @@ extern "C" OsTaskSuspend = PT_EXITED, OsTaskExit = PT_ENDED, OsTaskNotExist = -1, - }OsTaskStatus; + } OsTaskStatus; typedef char (*TaskFunction)(OsTaskId, void *); @@ -42,18 +48,19 @@ extern "C" const char *TaskName(OsTaskId taskId); - // Call TASK_DELETE, it will identify this task or not. int TaskDelete(OsTaskId taskId); - // Call TASK_SUSPEND, it will identify this task or not. int TaskSuspend(OsTaskId taskId); + // Resume the task from OsTaskSuspend. int TaskResume(OsTaskId taskId); + // Get the OsTaskStatus. OsTaskStatus TaskStatus(OsTaskId taskId); - void OsInit(void); + int OsInit(void); + // Start scheduling all the tasks, only return while all tasks are OsTaskExit or OsTaskNotExist. void OsStart(void); #if __cplusplus diff --git a/pt-osConfig.h b/pt-osConfig.h index 19cbe4b..d1ef6ca 100644 --- a/pt-osConfig.h +++ b/pt-osConfig.h @@ -1,8 +1,11 @@ #ifndef _OS_CONFIG_H_ #define _OS_CONFIG_H_ - +// Length of TaskName. +// may undef or set to zero for less ram resource. #define osMaxNameLen (16) + +// Number of maximum threads support #define osMaxThreads (64) #include diff --git a/tests/1p1c.cpp b/tests/1p1c.cpp index c09f9e1..4c1ac60 100644 --- a/tests/1p1c.cpp +++ b/tests/1p1c.cpp @@ -1,8 +1,4 @@ -#include "tz_ringbuf.hpp" -#include "pt-os.h" -#include -#include -#include "test.h" +#include "os_test.h" static constexpr int kThreadNum = 1; @@ -34,7 +30,7 @@ static inline int TestCheck() DumpData(name, kConsData_[i]); } - if (testFailed) printf("Test failed.\n"); + if (testFailed) OS_TRACE("Test failed.\n"); return testFailed ? 1 : 0; } @@ -42,7 +38,7 @@ static TASK_DECLARE(prodTask(OsTaskId taskId, void *param)) { static int i = 1; TASK_BEGIN(taskId); - printf("%s Begin\n", TaskName(taskId)); + OS_TRACE("%s Begin\n", TaskName(taskId)); while (1) { TASK_WAIT_UNTIL(taskId, !rb_.full()); @@ -59,7 +55,7 @@ static TASK_DECLARE(consTask(OsTaskId taskId, void *param)) static int i = 1; int v; TASK_BEGIN(taskId); - printf("%s Begin\n", TaskName(taskId)); + OS_TRACE("%s Begin\n", TaskName(taskId)); while (1) { TASK_WAIT_UNTIL(taskId, !rb_.empty()); @@ -78,7 +74,7 @@ static TASK_DECLARE(consTask(OsTaskId taskId, void *param)) int Test1p1c() { - printf("======== %s ========\n", __FUNCTION__); + OS_TRACE("======== %s ========\n", __FUNCTION__); TestInit(); OsInit(); diff --git a/tests/1p2c.cpp b/tests/1p2c.cpp index 7f1e3eb..cd7c597 100644 --- a/tests/1p2c.cpp +++ b/tests/1p2c.cpp @@ -1,8 +1,4 @@ -#include "tz_ringbuf.hpp" -#include "pt-os.h" -#include -#include -#include "test.h" +#include "os_test.h" static constexpr int kThreadNum = 2; @@ -32,7 +28,7 @@ static inline int TestCheck() sprintf(name, "CONS%d", i); DumpData(name, kConsData_[i]); } - if (testFailed) printf("Test failed.\n"); + if (testFailed) OS_TRACE("Test failed.\n"); return testFailed ? 1 : 0; } @@ -40,7 +36,7 @@ static TASK_DECLARE(prodTask(OsTaskId taskId, void *param)) { static int i = 1; TASK_BEGIN(taskId); - printf("%s Begin\n", TaskName(taskId)); + OS_TRACE("%s Begin\n", TaskName(taskId)); while (1) { TASK_WAIT_UNTIL(taskId, !rb_.full()); @@ -57,7 +53,7 @@ static TASK_DECLARE(consTask(OsTaskId taskId, void *param)) static int i = 1; int v; TASK_BEGIN(taskId); - printf("%s Begin\n", TaskName(taskId)); + OS_TRACE("%s Begin\n", TaskName(taskId)); while (1) { TASK_WAIT_UNTIL(taskId, !rb_.empty()); @@ -71,7 +67,7 @@ static TASK_DECLARE(consTask(OsTaskId taskId, void *param)) i++; if (i > testCount) { - printf("%s delete %s\n", TaskName(taskId), TaskName(kConsId_[(long)param ^ 1])); + OS_TRACE("%s delete %s\n", TaskName(taskId), TaskName(kConsId_[(long)param ^ 1])); TaskDelete(kConsId_[(long)param ^ 1]); TASK_EXIT(taskId); } @@ -82,7 +78,7 @@ static TASK_DECLARE(consTask(OsTaskId taskId, void *param)) int Test1p2c() { - printf("======== %s ========\n", __FUNCTION__); + OS_TRACE("======== %s ========\n", __FUNCTION__); TestInit(); OsInit(); diff --git a/tests/2p1c.cpp b/tests/2p1c.cpp index 7ae808a..60adf62 100644 --- a/tests/2p1c.cpp +++ b/tests/2p1c.cpp @@ -1,8 +1,4 @@ -#include "tz_ringbuf.hpp" -#include "pt-os.h" -#include -#include -#include "test.h" +#include "os_test.h" static constexpr int kThreadNum = 2; @@ -32,7 +28,7 @@ static inline int TestCheck() sprintf(name, "CONS%d", i); DumpData(name, kConsData_[i]); } - if (testFailed) printf("Test failed.\n"); + if (testFailed) OS_TRACE("Test failed.\n"); return testFailed ? 1 : 0; } @@ -40,13 +36,13 @@ static TASK_DECLARE(prodTask(OsTaskId taskId, void *param)) { static int i = 1; TASK_BEGIN(taskId); - printf("%s Begin\n", TaskName(taskId)); + OS_TRACE("%s Begin\n", TaskName(taskId)); while (1) { TASK_WAIT_UNTIL(taskId, !rb_.full()); if (i > testCount) { - printf("%s delete %s.\n", TaskName(taskId), TaskName(kProdId_[0])); + OS_TRACE("%s delete %s.\n", TaskName(taskId), TaskName(kProdId_[0])); TaskDelete(kProdId_[0]); TASK_EXIT(taskId); } @@ -55,8 +51,8 @@ static TASK_DECLARE(prodTask(OsTaskId taskId, void *param)) i++; if (taskId == kProdId_[0] && i > testCount/2) { - printf("%s suspend.\n", TaskName(taskId)); - TASK_SUSPEND(taskId); + OS_TRACE("%s suspend.\n", TaskName(taskId)); + TaskSuspend(OsSelfId); } } TASK_END(taskId); @@ -67,7 +63,7 @@ static TASK_DECLARE(consTask(OsTaskId taskId, void *param)) static int i = 1; int v; TASK_BEGIN(taskId); - printf("%s Begin\n", TaskName(taskId)); + OS_TRACE("%s Begin\n", TaskName(taskId)); while (1) { TASK_WAIT_UNTIL(taskId, !rb_.empty()); @@ -86,7 +82,7 @@ static TASK_DECLARE(consTask(OsTaskId taskId, void *param)) int Test2p1c() { - printf("======== %s ========\n", __FUNCTION__); + OS_TRACE("======== %s ========\n", __FUNCTION__); TestInit(); OsInit(); diff --git a/tests/main.cpp b/tests/main.cpp index 787607c..cf34ca5 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -1,26 +1,23 @@ -#include "tz_ringbuf.hpp" -#include "pt-os.h" -#include -#include -#include "test.h" +#include "os_test.h" void DumpData(const char *name, tzhu::ringbuf &kData) { int v; - printf("%s: %ld\n",name,kData.size()); + OS_TRACE("%s: %ld\n",name,kData.size()); for (int j = 0; kData.size() > 1; j++) { kData.pop(v); - printf("%d, ", v); + OS_TRACE("%d, ", v); } if( true == kData.pop(v)) - printf("%d\n", v); + OS_TRACE("%d\n", v); } int Test1p1c(); int Test2p1c(); int Test1p2c(); int TestResume(); +int TestSubfunction(); int main() { @@ -29,5 +26,6 @@ int main() rc += Test1p2c(); rc += Test2p1c(); rc += TestResume(); + rc += TestSubfunction(); return rc; } \ No newline at end of file diff --git a/tests/os_test.h b/tests/os_test.h new file mode 100644 index 0000000..79e9c6a --- /dev/null +++ b/tests/os_test.h @@ -0,0 +1,15 @@ +#ifndef _OS_TEST_H_ +#define _OS_TEST_H_ + +#include +#include +#include +#include "pt-os.h" + +#define testCount 100 + +#define OS_TRACE(...) printf(__VA_ARGS__) + +void DumpData(const char *name, tzhu::ringbuf &kData); + +#endif // _OS_TEST_H_ diff --git a/tests/resume.cpp b/tests/resume.cpp index c1dcdd5..015f209 100644 --- a/tests/resume.cpp +++ b/tests/resume.cpp @@ -1,8 +1,4 @@ -#include "tz_ringbuf.hpp" -#include "pt-os.h" -#include -#include -#include "test.h" +#include "os_test.h" static constexpr int kThreadNum = 2; @@ -15,24 +11,21 @@ static OsTaskId kConsId_[kThreadNum]; static tzhu::ringbuf kProdData_[kThreadNum]; static tzhu::ringbuf kConsData_[kThreadNum]; -static inline void TestInit() -{ - testFailed = false; -} +static inline void TestInit() { testFailed = false; } static inline int TestCheck() { char name[16]; - for(int i = 0; i < kThreadNum; i++) + for (int i = 0; i < kThreadNum; i++) { sprintf(name, "RPOD%d", i); DumpData(name, kProdData_[i]); } - for(int i = 0; i < kThreadNum; i++) - { + for (int i = 0; i < kThreadNum; i++) + { sprintf(name, "CONS%d", i); DumpData(name, kConsData_[i]); } - if (testFailed) printf("Test failed.\n"); + if (testFailed) OS_TRACE("Test failed.\n"); return testFailed ? 1 : 0; } @@ -40,7 +33,7 @@ static TASK_DECLARE(prodTask(OsTaskId taskId, void *param)) { static int i = 1; TASK_BEGIN(taskId); - printf("%s Begin\n", TaskName(taskId)); + OS_TRACE("%s Begin\n", TaskName(OsSelfId)); while (1) { TASK_WAIT_UNTIL(taskId, !rb_.full()); @@ -56,7 +49,7 @@ static TASK_DECLARE(consTask(OsTaskId taskId, void *param)) static int i = 1; int v; TASK_BEGIN(taskId); - printf("%s Begin\n", TaskName(taskId)); + OS_TRACE("%s Begin\n", TaskName(OsSelfId)); while (1) { TASK_WAIT_UNTIL(taskId, !rb_.empty()); @@ -67,25 +60,25 @@ static TASK_DECLARE(consTask(OsTaskId taskId, void *param)) testFailed = true; TASK_EXIT(taskId); } - if (i == testCount/4*1) + if (i == testCount / 4 * 1) { - printf("%s suspend %s\n", TaskName(taskId), TaskName(kProdId_[0])); + OS_TRACE("%s suspend %s\n", TaskName(taskId), TaskName(kProdId_[0])); TaskSuspend(kProdId_[0]); } - else if (i == testCount/4*2) + else if (i == testCount / 4 * 2) { - printf("%s resume %s\n", TaskName(taskId), TaskName(kProdId_[0])); + OS_TRACE("%s resume %s\n", TaskName(taskId), TaskName(kProdId_[0])); TaskResume(kProdId_[0]); } - else if (i == testCount/4*3) + else if (i == testCount / 4 * 3) { - printf("%s suspend %s\n", TaskName(taskId), TaskName(kProdId_[1])); + OS_TRACE("%s suspend %s\n", TaskName(taskId), TaskName(kProdId_[1])); TaskSuspend(kProdId_[1]); } i++; if (i > testCount) { - printf("%s Kill %s, %s\n", TaskName(taskId), TaskName(kProdId_[0]), TaskName(kProdId_[1])); + OS_TRACE("%s Kill %s, %s\n", TaskName(taskId), TaskName(kProdId_[0]), TaskName(kProdId_[1])); TaskDelete(kProdId_[0]); TaskDelete(kProdId_[1]); TASK_EXIT(taskId); @@ -96,7 +89,7 @@ static TASK_DECLARE(consTask(OsTaskId taskId, void *param)) int TestResume() { - printf("======== %s ========\n", __FUNCTION__); + OS_TRACE("======== %s ========\n", __FUNCTION__); TestInit(); OsInit(); @@ -104,6 +97,6 @@ int TestResume() kProdId_[1] = RegisterTask("prodTask2", prodTask, (void *)1); kConsId_[0] = RegisterTask("consTask", consTask, (void *)0); OsStart(); - + return TestCheck(); } \ No newline at end of file diff --git a/tests/subfunction.cpp b/tests/subfunction.cpp new file mode 100644 index 0000000..1f8df8c --- /dev/null +++ b/tests/subfunction.cpp @@ -0,0 +1,116 @@ +#include "os_test.h" + +static constexpr int kThreadNum = 2; + +static tzhu::ringbuf rb_; +static volatile bool testFailed; + +static OsTaskId kProdId_[kThreadNum]; +static OsTaskId kConsId_[kThreadNum]; + +static tzhu::ringbuf kProdData_[kThreadNum]; +static tzhu::ringbuf kConsData_[kThreadNum]; + +static inline void TestInit() { testFailed = false; } +static inline int TestCheck() +{ + char name[16]; + for (int i = 0; i < kThreadNum; i++) + { + sprintf(name, "RPOD%d", i); + DumpData(name, kProdData_[i]); + } + for (int i = 0; i < kThreadNum; i++) + { + sprintf(name, "CONS%d", i); + DumpData(name, kConsData_[i]); + } + if (testFailed) OS_TRACE("Test failed.\n"); + return testFailed ? 1 : 0; +} + +void prodSubFunction(long id) +{ + static int i = 1; + TaskWaitUntil(!rb_.full()); + rb_.push(i); + kProdData_[id].push(i); + OS_TRACE("%s %d\n", TaskName(OsSelfId), i); + i++; +} + +static TASK_DECLARE(prodTask(OsTaskId taskId, void *param)) +{ + TASK_BEGIN(taskId); + OS_TRACE("%s Begin\n", TaskName(OsSelfId)); + while (1) + { + prodSubFunction((long)param); + TASK_YIELD(taskId); + } + TASK_END(taskId); +} + +int consSubFunction(long id) +{ + int v; + TaskWaitUntil(!rb_.empty()); + rb_.pop(v); + kConsData_[id].push(v); + return v; +} + +static TASK_DECLARE(consTask(OsTaskId taskId, void *param)) +{ + static int i = 1; + int v; + TASK_BEGIN(taskId); + OS_TRACE("%s Begin\n", TaskName(OsSelfId)); + while (1) + { + v = consSubFunction((long)param); + if (v != i) + { + testFailed = true; + TASK_EXIT(taskId); + } + if (i == testCount / 4 * 1) + { + OS_TRACE("%s suspend %s @%d\n", TaskName(taskId), TaskName(kProdId_[0]), i); + TaskSuspend(kProdId_[0]); + } + else if (i == testCount / 4 * 2) + { + OS_TRACE("%s resume %s @%d\n", TaskName(taskId), TaskName(kProdId_[0]), i); + TaskResume(kProdId_[0]); + } + else if (i == testCount / 4 * 3) + { + OS_TRACE("%s suspend %s @%d\n", TaskName(taskId), TaskName(kProdId_[1]), i); + TaskSuspend(kProdId_[1]); + } + i++; + if (i > testCount) + { + OS_TRACE("%s Kill %s, %s\n", TaskName(taskId), TaskName(kProdId_[0]), TaskName(kProdId_[1])); + TaskDelete(kProdId_[0]); + TaskDelete(kProdId_[1]); + TASK_EXIT(taskId); + }; + } + TASK_END(taskId); +} + +int TestSubfunction() +{ + OS_TRACE("======== %s ========\n", __FUNCTION__); + TestInit(); + + OsInit(); + kProdId_[0] = RegisterTask("prodTask1", prodTask, (void *)0); + kProdId_[1] = RegisterTask("prodTask2", prodTask, (void *)1); + kConsId_[0] = RegisterTask("consTask", consTask, (void *)0); + OsStart(); + + return TestCheck(); +} \ No newline at end of file diff --git a/tests/test.h b/tests/test.h deleted file mode 100644 index 79092f0..0000000 --- a/tests/test.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _TEST_H_ -#define _TEST_H_ - -#define testCount 100 - -void DumpData(const char *name, tzhu::ringbuf &kData); - -#endif // _TEST_H_ \ No newline at end of file