add FreeRTOS support for PIThread PIMutex PIConditionVariable
This commit is contained in:
@@ -19,27 +19,40 @@
|
||||
|
||||
#include "piincludes_p.h"
|
||||
#include "pithread.h"
|
||||
#include "pisystemtests.h"
|
||||
#include "piintrospection_threads.h"
|
||||
#ifndef MICRO_PIP
|
||||
# include "pisystemtests.h"
|
||||
#endif
|
||||
#include <signal.h>
|
||||
#ifdef WINDOWS
|
||||
#if defined(WINDOWS)
|
||||
# define __THREAD_FUNC_RET__ uint __stdcall
|
||||
#elif defined(FREERTOS)
|
||||
# define __THREAD_FUNC_RET__ void
|
||||
#else
|
||||
# define __THREAD_FUNC_RET__ void*
|
||||
#endif
|
||||
#ifndef FREERTOS
|
||||
# define __THREAD_FUNC_END__ 0
|
||||
#else
|
||||
# define __THREAD_FUNC_END__
|
||||
#endif
|
||||
#if defined(LINUX)
|
||||
# include <sys/syscall.h>
|
||||
# define gettid() syscall(SYS_gettid)
|
||||
#endif
|
||||
#if defined(MAC_OS) || defined(BLACKBERRY) || defined(FREERTOS)
|
||||
#if defined(MAC_OS) || defined(BLACKBERRY)
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
__THREAD_FUNC_RET__ thread_function(void * t) {((PIThread*)t)->__thread_func__(); return 0;}
|
||||
__THREAD_FUNC_RET__ thread_function_once(void * t) {((PIThread*)t)->__thread_func_once__(); return 0;}
|
||||
|
||||
#define REGISTER_THREAD(t) __PIThreadCollection::instance()->registerThread(t)
|
||||
#define UNREGISTER_THREAD(t) __PIThreadCollection::instance()->unregisterThread(t)
|
||||
__THREAD_FUNC_RET__ thread_function(void * t) {((PIThread*)t)->__thread_func__(); return __THREAD_FUNC_END__;}
|
||||
__THREAD_FUNC_RET__ thread_function_once(void * t) {((PIThread*)t)->__thread_func_once__(); return __THREAD_FUNC_END__;}
|
||||
|
||||
#ifndef MICRO_PIP
|
||||
# define REGISTER_THREAD(t) __PIThreadCollection::instance()->registerThread(t)
|
||||
# define UNREGISTER_THREAD(t) __PIThreadCollection::instance()->unregisterThread(t)
|
||||
#else
|
||||
# define REGISTER_THREAD(t)
|
||||
# define UNREGISTER_THREAD(t)
|
||||
#endif
|
||||
|
||||
/*! \class PIThread
|
||||
* @brief Thread class
|
||||
@@ -90,6 +103,7 @@ end();
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MICRO_PIP
|
||||
|
||||
__PIThreadCollection *__PIThreadCollection::instance() {
|
||||
return __PIThreadCollection_Initializer__::__instance__;
|
||||
@@ -158,15 +172,17 @@ __PIThreadCollection_Initializer__::~__PIThreadCollection_Initializer__() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // MICRO_PIP
|
||||
|
||||
|
||||
PRIVATE_DEFINITION_START(PIThread)
|
||||
#ifndef WINDOWS
|
||||
#if defined(WINDOWS)
|
||||
void * thread;
|
||||
#elif defined(FREERTOS)
|
||||
TaskHandle_t thread;
|
||||
#else
|
||||
pthread_t thread;
|
||||
sched_param sparam;
|
||||
#else
|
||||
void * thread;
|
||||
#endif
|
||||
PRIVATE_DEFINITION_END(PIThread)
|
||||
|
||||
@@ -267,22 +283,22 @@ void PIThread::terminate() {
|
||||
terminating = running_ = false;
|
||||
tid_ = -1;
|
||||
//PICout(PICoutManipulators::DefaultControls) << "terminate" << PRIVATE->thread;
|
||||
#ifndef WINDOWS
|
||||
# ifdef ANDROID
|
||||
# ifndef WINDOWS
|
||||
# ifdef ANDROID
|
||||
pthread_kill(PRIVATE->thread, SIGTERM);
|
||||
# else
|
||||
# else
|
||||
//pthread_kill(PRIVATE->thread, SIGKILL);
|
||||
//void * ret(0);
|
||||
pthread_cancel(PRIVATE->thread);
|
||||
//pthread_join(PRIVATE->thread, &ret);
|
||||
# endif
|
||||
#else
|
||||
# endif
|
||||
# else
|
||||
TerminateThread(PRIVATE->thread, 0);
|
||||
CloseHandle(PRIVATE->thread);
|
||||
#endif
|
||||
# endif
|
||||
PRIVATE->thread = 0;
|
||||
end();
|
||||
#endif
|
||||
#endif //FREERTOS
|
||||
PIINTROSPECTION_THREAD_STOP(this);
|
||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "terminate ok" << running_;
|
||||
}
|
||||
@@ -290,27 +306,31 @@ void PIThread::terminate() {
|
||||
|
||||
int PIThread::priority2System(PIThread::Priority p) {
|
||||
switch (p) {
|
||||
# ifdef QNX
|
||||
#if defined(QNX)
|
||||
case piLowerst: return 8;
|
||||
case piLow: return 9;
|
||||
case piNormal: return 10;
|
||||
case piHigh: return 11;
|
||||
case piHighest: return 12;
|
||||
# else
|
||||
# ifdef WINDOWS
|
||||
#elif defined(WINDOWS)
|
||||
case piLowerst: return -2;
|
||||
case piLow: return -1;
|
||||
case piNormal: return 0;
|
||||
case piHigh: return 1;
|
||||
case piHighest: return 2;
|
||||
# else
|
||||
#elif defined(FREERTOS)
|
||||
case piLowerst: return 2;
|
||||
case piLow: return 3;
|
||||
case piNormal: return 4;
|
||||
case piHigh: return 5;
|
||||
case piHighest: return 6;
|
||||
#else
|
||||
case piLowerst: return 2;
|
||||
case piLow: return 1;
|
||||
case piNormal: return 0;
|
||||
case piHigh: return -1;
|
||||
case piHighest: return -2;
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
default: return 0;
|
||||
}
|
||||
return 0;
|
||||
@@ -320,11 +340,11 @@ int PIThread::priority2System(PIThread::Priority p) {
|
||||
bool PIThread::_startThread(void * func) {
|
||||
terminating = false;
|
||||
running_ = true;
|
||||
#ifndef WINDOWS
|
||||
#if !defined(WINDOWS) && !defined(FREERTOS)
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
int ret = pthread_create(&PRIVATE->thread, &attr, (void*(*)(void*))func, this);
|
||||
int ret = pthread_create(&PRIVATE->thread, &attr, (__THREAD_FUNC_RET__(*)(void*))func, this);
|
||||
//PICout(PICoutManipulators::DefaultControls) << "pthread_create" << PRIVATE->thread;
|
||||
pthread_attr_destroy(&attr);
|
||||
if (ret == 0) {
|
||||
@@ -332,22 +352,32 @@ bool PIThread::_startThread(void * func) {
|
||||
pthread_setname_np(((PIString&)name().elided(15, 0.4f).resize(15, PIChar('\0'))).dataAscii());
|
||||
pthread_threadid_np(PRIVATE->thread, (__uint64_t*)&tid_);
|
||||
# else
|
||||
# ifdef FREERTOS
|
||||
tid_ = PRIVATE->thread;
|
||||
# else
|
||||
pthread_setname_np(PRIVATE->thread, ((PIString&)name().elided(15, 0.4f).resize(15, PIChar('\0'))).dataAscii());
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
#endif
|
||||
#ifdef WINDOWS
|
||||
if (PRIVATE->thread) CloseHandle(PRIVATE->thread);
|
||||
# ifdef CC_GCC
|
||||
PRIVATE->thread = (void *)_beginthreadex(0, 0, (unsigned(__stdcall*)(void*))func, this, 0, 0);
|
||||
PRIVATE->thread = (void *)_beginthreadex(0, 0, (__THREAD_FUNC_RET__(*)(void*))func, this, 0, 0);
|
||||
# else
|
||||
PRIVATE->thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)func, this, 0, 0);
|
||||
# endif
|
||||
if (PRIVATE->thread != 0) {
|
||||
#endif
|
||||
#ifdef FREERTOS
|
||||
if (xTaskCreate(
|
||||
(__THREAD_FUNC_RET__(*)(void*))func,
|
||||
((PIString&)name().elided(15, 0.4f).resize(15, PIChar('\0'))).dataAscii(), // A name just for humans
|
||||
128, // This stack size can be checked & adjusted by reading the Stack Highwater
|
||||
this,
|
||||
priority_,
|
||||
&PRIVATE->thread
|
||||
) == pdPASS) {
|
||||
tid_ = (llong)PRIVATE->thread;
|
||||
#endif
|
||||
#ifndef FREERTOS
|
||||
setPriority(priority_);
|
||||
#endif
|
||||
return true;
|
||||
} else {
|
||||
running_ = false;
|
||||
@@ -360,10 +390,12 @@ bool PIThread::_startThread(void * func) {
|
||||
|
||||
|
||||
void PIThread::setPriority(PIThread::Priority prior) {
|
||||
#ifndef FREERTOS // FreeRTOS can't change priority runtime
|
||||
priority_ = prior;
|
||||
# ifndef WINDOWS
|
||||
if (!running_ || (PRIVATE->thread == 0)) return;
|
||||
#ifdef FREERTOS
|
||||
vTaskPrioritySet(PRIVATE->thread, priority2System(priority_));
|
||||
#else
|
||||
# ifndef WINDOWS
|
||||
//PICout(PICoutManipulators::DefaultControls) << "setPriority" << PRIVATE->thread;
|
||||
policy_ = 0;
|
||||
memset(&(PRIVATE->sparam), 0, sizeof(PRIVATE->sparam));
|
||||
@@ -503,18 +535,18 @@ void PIThread::_endThread() {
|
||||
//PICout(PICoutManipulators::DefaultControls) << "pthread_exit" << (__privateinitializer__.p)->thread;
|
||||
UNREGISTER_THREAD(this);
|
||||
PIINTROSPECTION_THREAD_STOP(this);
|
||||
#ifndef WINDOWS
|
||||
pthread_detach(PRIVATE->thread);
|
||||
PRIVATE->thread = 0;
|
||||
#endif
|
||||
#ifndef WINDOWS
|
||||
pthread_exit(0);
|
||||
#else
|
||||
#if defined(WINDOWS)
|
||||
# ifdef CC_GCC
|
||||
_endthreadex(0);
|
||||
# else
|
||||
ExitThread(0);
|
||||
# endif
|
||||
#elif defined(FREERTOS)
|
||||
PRIVATE->thread = 0;
|
||||
#else
|
||||
pthread_detach(PRIVATE->thread);
|
||||
PRIVATE->thread = 0;
|
||||
pthread_exit(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -558,8 +590,10 @@ void PIThread::runOnce(PIObject * object, const char * handler, const PIString &
|
||||
delete t;
|
||||
return;
|
||||
}
|
||||
#ifndef MICRO_PIP
|
||||
__PIThreadCollection::instance()->startedAuto(t);
|
||||
CONNECTU(t, stopped, __PIThreadCollection::instance(), stoppedAuto);
|
||||
#endif
|
||||
t->startOnce();
|
||||
}
|
||||
|
||||
@@ -568,8 +602,10 @@ void PIThread::runOnce(std::function<void ()> func, const PIString & name) {
|
||||
PIThread * t = new PIThread();
|
||||
t->setName(name);
|
||||
t->setSlot(func);
|
||||
#ifndef MICRO_PIP
|
||||
__PIThreadCollection::instance()->startedAuto(t);
|
||||
CONNECTU(t, stopped, __PIThreadCollection::instance(), stoppedAuto);
|
||||
#endif
|
||||
t->startOnce();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user