add FreeRTOS support for PIThread PIMutex PIConditionVariable
This commit is contained in:
@@ -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"
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user