add FreeRTOS support for PIThread PIMutex PIConditionVariable

This commit is contained in:
Andrey
2022-01-21 14:15:42 +03:00
parent 7403ee67be
commit 8296e9a32b
9 changed files with 173 additions and 77 deletions

View File

@@ -18,7 +18,10 @@
"srcFilter": [ "srcFilter": [
"+<libs/main/core/*.cpp>", "+<libs/main/core/*.cpp>",
"+<libs/main/containers/*.cpp>", "+<libs/main/containers/*.cpp>",
"+<libs/main/math/*.cpp>" "+<libs/main/math/*.cpp>",
"+<libs/main/thread/*.cpp>",
"+<libs/main/io_uutils/*.cpp>",
"+<libs/main/geo/*.cpp>"
], ],
"extraScript": "platformio_pre.py", "extraScript": "platformio_pre.py",
"flags": "-DPIP_FREERTOS" "flags": "-DPIP_FREERTOS"

View File

@@ -18,10 +18,10 @@
*/ */
#include "piobject.h" #include "piobject.h"
#include "pisysteminfo.h"
#include "pithread.h" #include "pithread.h"
#include "piconditionvar.h" #include "piconditionvar.h"
#ifndef MICRO_PIP #ifndef MICRO_PIP
# include "pisysteminfo.h"
# include "pifile.h" # include "pifile.h"
#endif #endif
@@ -589,6 +589,7 @@ void PIObject::dump(const PIString & line_prefix) const {
} }
#ifndef MICRO_PIP
void dumpApplication() { void dumpApplication() {
PIMutexLocker _ml(PIObject::mutexObjects()); PIMutexLocker _ml(PIObject::mutexObjects());
//printf("dump application ...\n"); //printf("dump application ...\n");
@@ -615,7 +616,6 @@ void dumpApplication() {
} }
#ifndef MICRO_PIP
bool dumpApplicationToFile(const PIString & path) { bool dumpApplicationToFile(const PIString & path) {
PIFile f(path + "_tmp"); PIFile f(path + "_tmp");
f.setName("__S__DumpFile"); f.setName("__S__DumpFile");

View File

@@ -37,11 +37,13 @@
typedef void (*Handler)(void * ); typedef void (*Handler)(void * );
class PIP_EXPORT PIObject { class PIP_EXPORT PIObject {
#ifndef MICRO_PIP
friend class PIObjectManager; friend class PIObjectManager;
friend void dumpApplication(); friend void dumpApplication();
friend class PIIntrospection;
#endif
typedef PIObject __PIObject__; typedef PIObject __PIObject__;
typedef void __Parent__; typedef void __Parent__;
friend class PIIntrospection;
public: public:
NO_COPY_CLASS(PIObject) NO_COPY_CLASS(PIObject)
@@ -539,8 +541,9 @@ private:
}; };
#ifndef MICRO_PIP
PIP_EXPORT void dumpApplication(); PIP_EXPORT void dumpApplication();
PIP_EXPORT bool dumpApplicationToFile(const PIString & path); PIP_EXPORT bool dumpApplicationToFile(const PIString & path);
#endif
#endif // PIOBJECT_H #endif // PIOBJECT_H

View File

@@ -19,8 +19,9 @@
#include "pivarianttypes.h" #include "pivarianttypes.h"
#include "pipropertystorage.h" #include "pipropertystorage.h"
#include "piiodevice.h" #ifndef MICRO_PIP
# include "piiodevice.h"
#endif
int PIVariantTypes::Enum::selectedValue() const { int PIVariantTypes::Enum::selectedValue() const {
piForeachC (Enumerator & e, enum_list) piForeachC (Enumerator & e, enum_list)
@@ -83,7 +84,7 @@ PIStringList PIVariantTypes::Enum::names() const {
#ifndef MICRO_PIP
PIVariantTypes::IODevice::IODevice() { PIVariantTypes::IODevice::IODevice() {
mode = PIIODevice::ReadWrite; mode = PIIODevice::ReadWrite;
options = 0; options = 0;
@@ -125,7 +126,7 @@ PIString PIVariantTypes::IODevice::toPICout() const {
s << ")"; s << ")";
return s; return s;
} }
#endif // MICRO_PIP

View File

@@ -20,7 +20,7 @@
#include "piconditionvar.h" #include "piconditionvar.h"
#include "pithread.h" #include "pithread.h"
#include "pitime.h" #include "pitime.h"
#include "piincludes_p.h"
#ifdef WINDOWS #ifdef WINDOWS
# undef _WIN32_WINNT # undef _WIN32_WINNT
# define _WIN32_WINNT 0x0600 # define _WIN32_WINNT 0x0600
@@ -28,25 +28,32 @@
# include <windef.h> # include <windef.h>
# include <winbase.h> # include <winbase.h>
#endif #endif
#ifdef FREERTOS
# include <event_groups.h>
#endif
PRIVATE_DEFINITION_START(PIConditionVariable) PRIVATE_DEFINITION_START(PIConditionVariable)
#ifdef WINDOWS #if defined(WINDOWS)
CONDITION_VARIABLE nativeHandle; CONDITION_VARIABLE
#elif defined(FREERTOS)
EventGroupHandle_t
#else #else
pthread_cond_t nativeHandle; pthread_cond_t
#endif #endif
nativeHandle;
PRIVATE_DEFINITION_END(PIConditionVariable) PRIVATE_DEFINITION_END(PIConditionVariable)
PIConditionVariable::PIConditionVariable() { PIConditionVariable::PIConditionVariable() {
#ifdef WINDOWS #if defined(WINDOWS)
InitializeConditionVariable(&PRIVATE->nativeHandle); InitializeConditionVariable(&PRIVATE->nativeHandle);
#elif defined(FREERTOS)
PRIVATE->nativeHandle = xEventGroupCreate();
#else #else
pthread_condattr_t condattr; pthread_condattr_t condattr;
pthread_condattr_init(&condattr); pthread_condattr_init(&condattr);
# if !defined(MAC_OS) && !defined(FREERTOS) # if !defined(MAC_OS)
pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC); pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC);
# endif # endif
memset(&(PRIVATE->nativeHandle), 0, sizeof(PRIVATE->nativeHandle)); memset(&(PRIVATE->nativeHandle), 0, sizeof(PRIVATE->nativeHandle));
@@ -56,7 +63,9 @@ PIConditionVariable::PIConditionVariable() {
PIConditionVariable::~PIConditionVariable() { PIConditionVariable::~PIConditionVariable() {
#ifdef WINDOWS #if defined(WINDOWS)
#elif defined(FREERTOS)
vEventGroupDelete(PRIVATE->nativeHandle);
#else #else
pthread_cond_destroy(&PRIVATE->nativeHandle); pthread_cond_destroy(&PRIVATE->nativeHandle);
#endif #endif
@@ -64,8 +73,11 @@ PIConditionVariable::~PIConditionVariable() {
void PIConditionVariable::wait(PIMutex& lk) { void PIConditionVariable::wait(PIMutex& lk) {
#ifdef WINDOWS #if defined(WINDOWS)
SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), INFINITE); SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), INFINITE);
#elif defined(FREERTOS)
xEventGroupClearBits(PRIVATE->nativeHandle, 1);
xEventGroupWaitBits(PRIVATE->nativeHandle, 1, pdTRUE, pdTRUE, portMAX_DELAY);
#else #else
pthread_cond_wait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle()); pthread_cond_wait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle());
#endif #endif
@@ -77,8 +89,11 @@ void PIConditionVariable::wait(PIMutex& lk, const std::function<bool()>& conditi
while (true) { while (true) {
isCondition = condition(); isCondition = condition();
if (isCondition) break; if (isCondition) break;
#ifdef WINDOWS #if defined(WINDOWS)
SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), INFINITE); SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), INFINITE);
#elif defined(FREERTOS)
xEventGroupClearBits(PRIVATE->nativeHandle, 1);
xEventGroupWaitBits(PRIVATE->nativeHandle, 1, pdTRUE, pdTRUE, portMAX_DELAY);
#else #else
pthread_cond_wait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle()); pthread_cond_wait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle());
#endif #endif
@@ -88,8 +103,13 @@ void PIConditionVariable::wait(PIMutex& lk, const std::function<bool()>& conditi
bool PIConditionVariable::waitFor(PIMutex &lk, int timeoutMs) { bool PIConditionVariable::waitFor(PIMutex &lk, int timeoutMs) {
bool isNotTimeout; bool isNotTimeout;
#ifdef WINDOWS #if defined(WINDOWS)
isNotTimeout = SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), timeoutMs) != 0; isNotTimeout = SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), timeoutMs) != 0;
#elif defined(FREERTOS)
xEventGroupClearBits(PRIVATE->nativeHandle, 1);
EventBits_t uxBits;
uxBits = xEventGroupWaitBits(PRIVATE->nativeHandle, 1, pdTRUE, pdTRUE, timeoutMs / portTICK_PERIOD_MS);
isNotTimeout = (uxBits & 1) != 0;
#else #else
timespec expire_ts; timespec expire_ts;
PISystemTime st = PISystemTime::current(true); PISystemTime st = PISystemTime::current(true);
@@ -103,24 +123,32 @@ bool PIConditionVariable::waitFor(PIMutex &lk, int timeoutMs) {
bool PIConditionVariable::waitFor(PIMutex& lk, int timeoutMs, const std::function<bool()> &condition) { bool PIConditionVariable::waitFor(PIMutex& lk, int timeoutMs, const std::function<bool()> &condition) {
bool isCondition; bool isCondition;
#ifdef WINDOWS #if defined(WINDOWS) || defined(FREERTOS)
PITimeMeasurer measurer; PITimeMeasurer measurer;
#else #else
timespec expire_ts; timespec expire_ts;
PISystemTime st = PISystemTime::current(true); PISystemTime st = PISystemTime::current(true);
st.addMilliseconds(timeoutMs); st.addMilliseconds(timeoutMs);
st.toTimespec(&expire_ts); st.toTimespec(&expire_ts);
#endif
#ifdef FREERTOS
xEventGroupClearBits(PRIVATE->nativeHandle, 1);
#endif #endif
while (true) { while (true) {
isCondition = condition(); isCondition = condition();
if (isCondition) break; if (isCondition) break;
#ifdef WINDOWS bool isTimeout;
bool isTimeout = SleepConditionVariableCS( #if defined(WINDOWS)
isTimeout = SleepConditionVariableCS(
&PRIVATE->nativeHandle, &PRIVATE->nativeHandle,
(PCRITICAL_SECTION)lk.handle(), (PCRITICAL_SECTION)lk.handle(),
timeoutMs - (int)measurer.elapsed_m()) == 0; timeoutMs - (int)measurer.elapsed_m()) == 0;
#elif defined(FREERTOS)
EventBits_t uxBits;
uxBits = xEventGroupWaitBits(PRIVATE->nativeHandle, 1, pdTRUE, pdTRUE, (timeoutMs - (int)measurer.elapsed_m()) / portTICK_PERIOD_MS);
isTimeout = (uxBits & 1) == 0;
#else #else
bool isTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &expire_ts) != 0; isTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &expire_ts) != 0;
#endif #endif
if (isTimeout) return false; if (isTimeout) return false;
} }
@@ -129,8 +157,10 @@ bool PIConditionVariable::waitFor(PIMutex& lk, int timeoutMs, const std::functio
void PIConditionVariable::notifyOne() { void PIConditionVariable::notifyOne() {
#ifdef WINDOWS #if defined(WINDOWS)
WakeConditionVariable(&PRIVATE->nativeHandle); WakeConditionVariable(&PRIVATE->nativeHandle);
#elif defined(FREERTOS)
xEventGroupSetBits(PRIVATE->nativeHandle, 1);
#else #else
pthread_cond_signal(&PRIVATE->nativeHandle); pthread_cond_signal(&PRIVATE->nativeHandle);
#endif #endif
@@ -138,8 +168,10 @@ void PIConditionVariable::notifyOne() {
void PIConditionVariable::notifyAll() { void PIConditionVariable::notifyAll() {
#ifdef WINDOWS #if defined(WINDOWS)
WakeAllConditionVariable(&PRIVATE->nativeHandle); WakeAllConditionVariable(&PRIVATE->nativeHandle);
#elif defined(FREERTOS)
xEventGroupSetBits(PRIVATE->nativeHandle, 1);
#else #else
pthread_cond_broadcast(&PRIVATE->nativeHandle); pthread_cond_broadcast(&PRIVATE->nativeHandle);
#endif #endif

View File

@@ -36,8 +36,10 @@
#include "pimutex.h" #include "pimutex.h"
#include "piincludes_p.h" #include "piincludes_p.h"
#ifdef WINDOWS #if defined(WINDOWS)
# include <synchapi.h> # include <synchapi.h>
#elif defined(FREERTOS)
# include <semphr.h>
#else #else
# include <pthread.h> # include <pthread.h>
#endif #endif
@@ -45,8 +47,10 @@
PRIVATE_DEFINITION_START(PIMutex) PRIVATE_DEFINITION_START(PIMutex)
#ifdef WINDOWS #if defined(WINDOWS)
CRITICAL_SECTION CRITICAL_SECTION
#elif defined(FREERTOS)
SemaphoreHandle_t
#else #else
pthread_mutex_t pthread_mutex_t
#endif #endif
@@ -65,8 +69,10 @@ PIMutex::~PIMutex() {
void PIMutex::lock() { void PIMutex::lock() {
#ifdef WINDOWS #if defined(WINDOWS)
EnterCriticalSection(&(PRIVATE->mutex)); EnterCriticalSection(&(PRIVATE->mutex));
#elif defined(FREERTOS)
xSemaphoreTake(PRIVATE->mutex, portMAX_DELAY);
#else #else
pthread_mutex_lock(&(PRIVATE->mutex)); pthread_mutex_lock(&(PRIVATE->mutex));
#endif #endif
@@ -74,8 +80,10 @@ void PIMutex::lock() {
void PIMutex::unlock() { void PIMutex::unlock() {
#ifdef WINDOWS #if defined(WINDOWS)
LeaveCriticalSection(&(PRIVATE->mutex)); LeaveCriticalSection(&(PRIVATE->mutex));
#elif defined(FREERTOS)
xSemaphoreGive(PRIVATE->mutex);
#else #else
pthread_mutex_unlock(&(PRIVATE->mutex)); pthread_mutex_unlock(&(PRIVATE->mutex));
#endif #endif
@@ -84,8 +92,10 @@ void PIMutex::unlock() {
bool PIMutex::tryLock() { bool PIMutex::tryLock() {
bool ret = bool ret =
#ifdef WINDOWS #if defined(WINDOWS)
(TryEnterCriticalSection(&(PRIVATE->mutex)) != 0); (TryEnterCriticalSection(&(PRIVATE->mutex)) != 0);
#elif defined(FREERTOS)
xSemaphoreTake(PRIVATE->mutex, 0);
#else #else
(pthread_mutex_trylock(&(PRIVATE->mutex)) == 0); (pthread_mutex_trylock(&(PRIVATE->mutex)) == 0);
#endif #endif
@@ -94,13 +104,19 @@ bool PIMutex::tryLock() {
void * PIMutex::handle() { void * PIMutex::handle() {
#ifdef FREERTOS
return PRIVATE->mutex;
#else
return (void*)&(PRIVATE->mutex); return (void*)&(PRIVATE->mutex);
#endif
} }
void PIMutex::init() { void PIMutex::init() {
#ifdef WINDOWS #if defined(WINDOWS)
InitializeCriticalSection(&(PRIVATE->mutex)); InitializeCriticalSection(&(PRIVATE->mutex));
#elif defined(FREERTOS)
PRIVATE->mutex = xSemaphoreCreateMutex();
#else #else
pthread_mutexattr_t attr; pthread_mutexattr_t attr;
memset(&attr, 0, sizeof(attr)); memset(&attr, 0, sizeof(attr));
@@ -114,8 +130,10 @@ void PIMutex::init() {
void PIMutex::destroy() { void PIMutex::destroy() {
#ifdef WINDOWS #if defined(WINDOWS)
DeleteCriticalSection(&(PRIVATE->mutex)); DeleteCriticalSection(&(PRIVATE->mutex));
#elif defined(FREERTOS)
vSemaphoreDelete(PRIVATE->mutex);
#else #else
pthread_mutex_destroy(&(PRIVATE->mutex)); pthread_mutex_destroy(&(PRIVATE->mutex));
#endif #endif

View File

@@ -24,7 +24,6 @@
#define PIMUTEX_H #define PIMUTEX_H
#include "piinit.h" #include "piinit.h"
#include <mutex>
class PIP_EXPORT PIMutex class PIP_EXPORT PIMutex

View File

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

View File

@@ -30,6 +30,8 @@
#include "piobject.h" #include "piobject.h"
class PIThread; class PIThread;
#ifndef MICRO_PIP
class PIIntrospectionThreads; class PIIntrospectionThreads;
class PIP_EXPORT __PIThreadCollection: public PIObject { class PIP_EXPORT __PIThreadCollection: public PIObject {
@@ -58,14 +60,16 @@ public:
}; };
static __PIThreadCollection_Initializer__ __PIThreadCollection_initializer__; static __PIThreadCollection_Initializer__ __PIThreadCollection_initializer__;
#endif // MICRO_PIP
typedef std::function<void(void *)> ThreadFunc; typedef std::function<void(void *)> ThreadFunc;
class PIP_EXPORT PIThread: public PIObject class PIP_EXPORT PIThread: public PIObject
{ {
PIOBJECT_SUBCLASS(PIThread, PIObject) PIOBJECT_SUBCLASS(PIThread, PIObject)
#ifndef MICRO_PIP
friend class PIIntrospectionThreads; friend class PIIntrospectionThreads;
#endif
public: public:
NO_COPY_CLASS(PIThread) NO_COPY_CLASS(PIThread)