FreeRTOS C++: passing arguments to a task in a class - task

My question is similar to this one but I need to pass arguments to the task.
I want to run 2 parallel instances of a task on an ESP32. So I create the task inside a class and a wrapper to prevent the
error: invalid use of non-static member function
Here is the task creation:
// Create parallel tasks
xTaskCreatePinnedToCore(
this->startForwardTask, /* Function to implement the task */
"Forward0", /* Name of the task */
1000, /* Stack size in words */
this,
/* (void*)&params0, /* Task input parameter */
20, /* Priority of the task */
NULL, /* Task handle */
0); /* Core where the task runs */
xTaskCreatePinnedToCore(
this->startForwardTask, /* Function to implement the task */
"Forward1", /* Name of the task */
1000, /* Stack size in words */
this,
/* (void*)&params1, /* Task input parameter */
20, /* Priority of the task */
NULL, /* Task handle */
1); /* Core where the task runs */
Then the task is :
void MLP::startForwardTask(void* _this) {
(MLP*)_this->forwardTask();
}
void MLP::forwardTask (void * parameters) {
argsStruct myArgs = *((argsStruct*)parameters);
// whatever
SemaphoreHandle_t barrierSemaphore = myArgs.semaphore;
xSemaphoreGive(barrierSemaphore);
vTaskDelete(NULL);
}
params0 and params1 are structs where I put the parameters I want to pass to the tasks.
// Create semaphore for tasks synchronization
SemaphoreHandle_t barrierSemaphore = xSemaphoreCreateCounting( 2, 0 );
// Arguments for the tasks
argsStruct params0 = {1, med, l, barrierSemaphore};
argsStruct params1 = {med + 1, end, l, barrierSemaphore};
I get the following error:
C:---\Arduino\libraries\MLP\MLP.cpp: In static member function 'static void MLP::startForwardTask(void*)':
C:---\Arduino\libraries\MLP\MLP.cpp:887:14: error: 'void*' is not a pointer-to-object type
(MLP*)_this->forwardTask();
^
exit status 1
In order to use the wrapper function, I had to pass the 'this' argument to the wrapping task. How can I pass the params0 and params1 arguments to the 'real' task (forwardTask) when I declare the tasks?
One other question: I create a counting semaphore to synchronize the 2 tasks and continue after both have ended. I passed the semaphore as an argument to both tasks (inside a struct). How can the method that created the tasks monitor this semaphore? Is this correct?
for (int i = 0; i < 2; i++) {
xSemaphoreTake(barrierSemaphore, portMAX_DELAY);
}

According to C++ operator precedence you need to properly cast _this before calling a method like this ((MLP*)_this)->forwardTask();
See https://en.cppreference.com/w/cpp/language/operator_precedence
I guess you want to wait for both tasks exit with the barrierSemaphore and I think it should work. Although dynamically creating/destroying tasks is usually not the preferred pattern in embedded systems..

Related

Dart: how to run static function/code "automatically"?

In Dart (Flutter) I would like to have some static code run without being explicitly invoked.
I tried this:
// File 1
class MyClass {
static int member = 42;
}
int dummy = 42;
and file 2:
// File 2
void main() {
int tmp = MyClass.member;
}
I put a breakpoint on the dummy = 2; line but it seemed to never be invoked.
I also tried:
// File 1
class MyClass {
static int member1 = 42;
static int member2 = SomeOtherClass.someFunc();
}
and file 2:
// File 2
void main() {
int tmp1 = MyClass.member1;
int tmp2 = MyClass.member2;
}
With this, SomeOtherClass.someFunc() was invoked when the int tmp2 = ... line was invoked.
I would like SomeOtherClass.someFunc() to be invoked without explicitly accessing MyClass.member2. I would like it invoked on any of the following triggers:
When the program starts (before main() is called).
OR, when code in a file in which MyClass is imported is invoked for the first time.
Is either of these possible in Dart?
This behavior is intentional and cannot be changed. As jamesdlin also explain, all static variables (class and global) in Dart are lazy evaluated and will first get a value with first attempt to access the value.
This is design is described in the Dart specification followed up with a reason for that design choice:
Static variable declarations with an initializing expression are initializedlazily.
The lazy semantics are given because we do not want a language where one tends to define expensive initialization computations, causing long application startup times. This is especially crucial for Dart, which must support the coding of client applications.
https://dart.dev/guides/language/specifications/DartLangSpec-v2.2.pdf

How to comprehend that "lua_Hook is called when it jumps back in the code(This event only happens while Lua is executing a Lua function.)"?

As per the documentation(https://www.lua.org/manual/5.3/manual.html#lua_sethook), which says[empasise mine]:
Argument f is the hook function. mask specifies on which events the
hook will be called: it is formed by a bitwise OR of the constants
LUA_MASKCALL, LUA_MASKRET, LUA_MASKLINE, and LUA_MASKCOUNT. The count
argument is only meaningful when the mask includes LUA_MASKCOUNT. For
each event, the hook is called as explained below:
The call hook: is called when the interpreter calls a function. The
hook is called just after Lua enters the new function, before the
function gets its arguments.
The return hook: is called when the
interpreter returns from a function. The hook is called just before
Lua leaves the function. There is no standard way to access the values
to be returned by the function.
The line hook: is called when the
interpreter is about to start the execution of a new line of code, or
when it jumps back in the code (even to the same line). (This event
only happens while Lua is executing a Lua function.)
How to comprehend that lua_Hook is called when it jumps back in the code(This event only happens while Lua is executing a Lua function?
We can look at the source (Lua 5.4):
int luaG_traceexec (lua_State *L, const Instruction *pc) {
-- some parts removed
if (mask & LUA_MASKLINE) {
if (npci == 0 || /* call linehook when enter a new function, */
pc <= L->oldpc || /* when jump back (loop), or when */
changedline(p, pcRel(L->oldpc, p), npci)) { /* enter new line */
int newline = luaG_getfuncline(p, npci);
luaD_hook(L, LUA_HOOKLINE, newline, 0, 0); /* call line hook */
}
}
return 1; /* keep 'trap' on */
}
As can be seen, LUA_HOOKLINE is called in three cases: (1) enter a new function, (2) jump back (loop), or (3) enter new line.
"Enter new line" is checked by a call to changedline:
static int changedline (const Proto *p, int oldpc, int newpc) {
while (oldpc++ < newpc) {
if (p->lineinfo[oldpc] != 0)
return (luaG_getfuncline(p, oldpc - 1) != luaG_getfuncline(p, newpc));
}
return 0; /* no line changes in the way */
}
This returns true if the new instruction is on a different line from the previous instruction.
luaG_getfuncline gets the line number for the instruction if there is debug information available. The function being checked is the active lua function based on the the current call info value.

The function of typedef block in IOS

Today I want to learn how to use typedef to define a block type. I read the related content from "IOS developer library". But I feel confused about some statement of the sentences.
As an example, you can define a type for a simple block with no arguments or return value, like this:
typedef void (^XYZSimpleBlock)(void);
You can then use your custom type for method parameters or when creating block variables:
XYZSimpleBlock anotherBlock = ^{
...
};
- (void)beginFetchWithCallbackBlock:(XYZSimpleBlock)callbackBlock {
...
callbackBlock();
}
Custom type definitions are particularly useful when dealing with blocks that return blocks or take other blocks as arguments. Consider the following example:
void (^(^complexBlock)(void (^)(void)))(void) = ^ (void (^aBlock)(void)) {
...
return ^{
...
};
};
The complexBlock variable refers to a block that takes another block as an argument (aBlock) and returns yet another block.
Rewriting the code to use a type definition makes this much more readable:
XYZSimpleBlock (^betterBlock)(XYZSimpleBlock) = ^ (XYZSimpleBlock aBlock) {
...
return ^{
...
};
}
The question I want to ask is that how to convert the expression from
void (^(^complexBlock)(void (^)(void)))(void)
to
XYZSimpleBlock (^betterBlock)(XYZSimpleBlock) = ^ (XYZSimpleBlock aBlock)
?

c++ pthread_create within method

Is there an easy way to create a new pthread each time a method is called?
I have a method activating in certain circumstances and it is the only way to commumicate with another program. I need to engage sleep and execute another method after said method is called, there is an option of another call during waiting - this is the reason i wanted to use threads.
I wanted to use standard:
pthread_create(&new_thread, NULL, threadbody() );
Put like this
std::vector<phtread_t> thread(20)
...
pthread_t new_thread;
int rc;
rc = pthread_create(&new_thread, NULL, threadbody() );
threads.push_back(new_thread);
But i either get the errors of bad using of (void *) functions.
argument of type ‘void* (App::)(void*)’ does not match ‘void* (*)(void*)
What am I doing wrong?
Your function is a non-static member of the class. This is a no-no since pthread_create is only meant to work in the C realm.
To offset this, you can have
class X
{
public:
static void* callback(void* p)
{
X* x = reinterpret_cast<X*>(p);
x->function();
return 0;
}
void function(void)
{
// do work here
}
};
X obj;
pthread_create(&new_thread, &obj, &X::callback);

pthread parallel processing

Need urgent help on thread: the goal here is the separtemask will take each image and separate different contours and for each contour in the image it will call handleobject thread. So every for loop will call the handeobject thread. However, object index variable needs to be passed in each thread. But only last value of objectndex is passed, this is becuase the speratemask function loops and repalces the value of obj.objindx and only the last value of obj.objindx is
passed to all the threads. Is there anyway to pass each objectindex
value in handleobject. The code runs fine if we uncomment the pthread_join(tid[objectIndex],NULL); but it will not give a parralel program
void separateMask(IplImage *maskImg)
{
for(r = contours; r != NULL; r = r->h_next)
{
cvSet(objectMaskImg, cvScalarAll(0), NULL);
CvScalar externalColor = cvScalarAll(0xff);
CvScalar holeColor = cvScalarAll(0x00);
int maxLevel = -1;
int thinkness = CV_FILLED;
int lineType = 8; /* 8-connected */
cvDrawContours(objectMaskImg, r, externalColor, holeColor, maxLevel, thinkness,lineType, cvPoint(0,0));;
obj.objectMaskImg1[objectIndex]=(IplImage *) malloc(sizeof(IplImage));
obj.objectMaskImg1[objectIndex]=objectMaskImg;
obj.objindx=objectIndex;
obj.intensityOut1=intensityOut;
obj.tasOut1=tasOut;
pthread_create(&tid[objectIndex],NULL,handleObject,(void *)&obj);
//pthread_join(tid[objectIndex],NULL);
printf("objectindx %d\n",obj.objindx);
objectIndex++;
}
// cvReleaseImage(&objectMaskImg);
//cvReleaseMemStorage(&storage);
printf("Exitng Separatemask\n");
}
void* handleObject(void *arg)
{
int i, j;
handle *hndl;
hndl=(handle *) malloc(sizeof(handle));
hndl=(handle*)arg;
pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&lock);
IplImage *pImg;
float statistics_ratio[3][9];
pthread_t tid3;
tas3 tas2;
pImg = cvLoadImage("image.tif", CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH);
if(pImg == NULL)
{
fprintf(stderr, "Fail to load image %s\n", "tiff file");
return ;
}
tas2.pImg1=pImg;
printf("tst%d\n",hndl->objindx);
tas2.x=hndl->objindx;
tas2.objectMaskImg1=hndl->objectMaskImg1[tas2.x];
tas2.statistics_ratio[3][9]=statistics_ratio[3][9];
double mean = average_intensity(pImg, tas2.objectMaskImg1);
int total = total_white(pImg, tas2.objectMaskImg1);
pthread_mutex_unlock(&lock);
printf("Exiting handle object thread_id %d\n\n", pthread_self());
}
This function appears to have issues
void* handleObject(void *arg)
Firstly
pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&lock);
this is a locally created mutex - but created WITHIN the thread function. So you lock it but since nothing else can see the mutex, why do you need it??? It gives no synchronization functionality if no other threads can see it.
Secondly
float statistics_ratio[3][9];
pthread_t tid3;
tas3 tas2;
pImg = cvLoadImage("image.tif", CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH);
if(pImg == NULL){
fprintf(stderr, "Fail to load image %s\n", "tiff file");
return ;
}
tas2.pImg1=pImg;
printf("tst%d\n",hndl->objindx);
tas2.x=hndl->objindx;
tas2.objectMaskImg1=hndl->objectMaskImg1[tas2.x];
tas2.statistics_ratio[3][9]=statistics_ratio[3][9];
you create a local uninitialised 2d float array statistics_ratio, do nothing with it then assign it to another locally created object member. This appears to be meaningless, as does the declaration of another pthread instance tid3.
It doesn't really matter since nothing else can see the thread but you return from inside this function if pImg == NULL without first unlocking the mutex.
It is very hard to see why your code doesnt work or what it is meant to do, but perhaps the things highlighted above may help. You are creating a lot of local variables within your thread functions which are not being used. I am not sure if you need some of these to be global instead - particularly the mutex (if indeed you need one at all).
I think your initial problem is that you're reusing the obj structure that you're passing to the created threads so you'll have data races where the thread just created will read information that's been overwritten with data intended for another thread.
The loop that creates the threads has the following structure:
for(r = contours; r != NULL; r = r->h_next)
{
// initialize obj with information for the thread
// ...
// create a thread and pass it a pointer to obj
pthread_create(&tid[objectIndex],NULL,handleObject,(void *)&obj);
// some other bookkeeping
}
Since you immediately re-initialize obj on the next loop iteration, who knows what data the thread function is going to get? That's why things work if you join the thread after creating it - the obj structure remains stable because the loop blocks until the thread is finished.
Change the loop to look something like:
for(r = contours; r != NULL; r = r->h_next)
{
// instead of using `obj`, allocate a struct using malloc
handle* threaddata = malloc(sizeof(handle); // note: I'm not sure if `handle` is the right type
// initialize *threaddata with information for the thread
// ...
// create a thread and pass it the threaddata pointer
pthread_create(&tid[objectIndex],NULL,handleObject,threaddata);
// some other bookkeeping
}
Then free() the data in the thread function after it is finished with with (ie., the thread creation code creates and initializes the block of data then passes ownership of it to the thread).
Note that this might not be as straightforward as it often is, becuase it looks like your obj structure already has some per-thread information in it (the objectMaskImg1 element looks to be an array it each element being intended for a separate thread). So you might need to do some refactoring of the data structure as well.
Finally, there are several other outright bugs such as immediately overwriting pointers to blocks allocated by malloc():
obj.objectMaskImg1[objectIndex]=(IplImage *) malloc(sizeof(IplImage));
obj.objectMaskImg1[objectIndex]=objectMaskImg;
and
hndl=(handle *) malloc(sizeof(handle));
hndl=(handle*)arg;
In addition to the pointless use of the mutex in the handleObject() thread function as mentioned by mathematician1975 (http://stackoverflow.com/a/11460092/12711).
A fair bit of the code in the thread function (copying or attempting to copy data locally, the mutex) appears to be stuff thrown in to try to fix problems without actually understanding what the problem is. I think you really need to get an understanding of where various data lives, how to copy it (as opposed to just copying a pointer to it), and how to manage the ownership of the data.

Resources