pthread questions
heya,
some question about pthread for RaspI:
1) is a short tutorial available how to setup, how to use it and make a couple of tasks run simultaneously - and at the end clean all and everything?
ps,
I'm using g++ for C++ libs additionally
--------------------------------------
edit:
found something!
some question about pthread for RaspI:
1) is a short tutorial available how to setup, how to use it and make a couple of tasks run simultaneously - and at the end clean all and everything?
ps,
I'm using g++ for C++ libs additionally
--------------------------------------
edit:
found something!
Last edited by davenull on Wed Nov 04, 2015 1:46 pm, edited 1 time in total.
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
Re: pthread questions
2) is it useful to link by
-D_REENTRANT
additionally for Raspberry Pi?
3) how is it possible to immediately stop or kill 1 task by main() or by another task ?
(e.g.,
a) immediately in case of emergency stop (no cleaning required necessarily) or
b) by a higher-priority task (in this case a cleaning would be helpful )
-D_REENTRANT
additionally for Raspberry Pi?
3) how is it possible to immediately stop or kill 1 task by main() or by another task ?
(e.g.,
a) immediately in case of emergency stop (no cleaning required necessarily) or
b) by a higher-priority task (in this case a cleaning would be helpful )
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
Re: pthread questions
Have a read of Chapter 4: Threads
of the Advanced Linux Programming manual, which can be downloaded from here:
https://archive.org/details/ost-compute ... rogramming
Before you start ask yourself the following questions:
Can the task be broken down into multiple threads that can run totally independently of each other with their own separate resources and or memory areas? Not all tasks are suitable for this sort of thing.
It takes quite a lot of effort to design and write code that uses multiple threads, and sometimes it is just not worth it if you are not going to get a serious increase in program throughput, on a multi core processor.
Debugging it can be a nightmare, especially if you run into deadlock or race conditions, because the design was flawed at the start.
If you have to kill a thread off, your original design is probably suspect.
of the Advanced Linux Programming manual, which can be downloaded from here:
https://archive.org/details/ost-compute ... rogramming
Before you start ask yourself the following questions:
Can the task be broken down into multiple threads that can run totally independently of each other with their own separate resources and or memory areas? Not all tasks are suitable for this sort of thing.
It takes quite a lot of effort to design and write code that uses multiple threads, and sometimes it is just not worth it if you are not going to get a serious increase in program throughput, on a multi core processor.
Debugging it can be a nightmare, especially if you run into deadlock or race conditions, because the design was flawed at the start.
If you have to kill a thread off, your original design is probably suspect.
Re: pthread questions
I'm already writing and using Multitasking programs since about 15 years, but not by C compilers but for different bytecode interpreters (sort of Java and this kind of stuff) which don't need compile parameters long enough to sink a ship - and I'm fine with killing tasks in case there's a need to do so. 

#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
Re: pthread questions
update:
2) is it useful to link by
-D_REENTRANT
additionally for Raspberry Pi?
3) how is it possible to immediately stop or kill 1 task by main() or by another task ?
(e.g.,
a) immediately in case of emergency stop (no cleaning required necessarily) or
b) by a higher-priority task (in this case a cleaning would be helpful )
4) how is it possible for a pthread task to make it run at a 1-2 higher priority level?
How many priority levels are possible generally?
I currently have
pthread_t thread1, thread2, thread2;
pthread_create(&thread1, NULL, thread2Go, NULL);
pthread_create(&thread2, NULL, thread3Go, NULL);
pthread_create(&thread3, NULL, thread4Go, NULL);
and want to make thread1 run in a very simple way by a 1-2x higher priority than the rest.
2) is it useful to link by
-D_REENTRANT
additionally for Raspberry Pi?
3) how is it possible to immediately stop or kill 1 task by main() or by another task ?
(e.g.,
a) immediately in case of emergency stop (no cleaning required necessarily) or
b) by a higher-priority task (in this case a cleaning would be helpful )
4) how is it possible for a pthread task to make it run at a 1-2 higher priority level?
How many priority levels are possible generally?
I currently have
pthread_t thread1, thread2, thread2;
pthread_create(&thread1, NULL, thread2Go, NULL);
pthread_create(&thread2, NULL, thread3Go, NULL);
pthread_create(&thread3, NULL, thread4Go, NULL);
and want to make thread1 run in a very simple way by a 1-2x higher priority than the rest.
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
Re: pthread questions
man pthreads
is probably a good place to start,
is probably a good place to start,
Re: pthread questions
pls what?
could you pls just answer the 3 questions quick, short, and simple?
could you pls just answer the 3 questions quick, short, and simple?
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
Re: pthread questions
*nix documentation is in manual pages. man is the command to view the manual page for a topic.davenull wrote:pls what?
could you pls just answer the 3 questions quick, short, and simple?
If you want to know about a function then man function. If you want to know about a topic or configuration file then man topic or man configuration file will likely have some information.
Re: pthread questions
no ideas by anyone?
I just needed the answers to the 3 questions (2-4), very quick, very short, and very simple, would this not be possible ?
I just needed the answers to the 3 questions (2-4), very quick, very short, and very simple, would this not be possible ?
2) is it useful to link by
-D_REENTRANT
additionally for Raspberry Pi?
3) how is it possible to immediately stop or kill 1 task by main() or by another task ?
(e.g.,
a) immediately in case of emergency stop (no cleaning required necessarily) or
b) by a higher-priority task (in this case a cleaning would be helpful )
4) how is it possible for a pthread task to make it run at a 1-2 higher priority level?
How many priority levels are possible generally?
I currently have
pthread_t thread1, thread2, thread2;
pthread_create(&thread1, NULL, thread2Go, NULL);
pthread_create(&thread2, NULL, thread3Go, NULL);
pthread_create(&thread3, NULL, thread4Go, NULL);
and want to make thread1 run in a very simple way by a 1-2x higher priority than the rest.
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
Re: pthread questions
The OP doesn't seem to have a solid grounding in thread usage, and his question comes across as a request for 1-on-1 tutoring, which probably isn't going to happen. The man pages are more helpful to people who already have some familiarity with the topic and need to review it and be reminded of details. For a great intro to thread usage and lots of examples, see the relevant chapters of The Linux Programming Interface by Michael Kerrisk.
Re: pthread questions
thanks, but first I need quick answers to my 3 simple question, this could not be so hard, is it?
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
Re: pthread questions
As long as you know that a "quick answer" to a "simple" question on multithreading isn't necessarily going to be he one you want. Reading up on pthreads (as suggested before) is a must. But if you want quick (I haven't done multithreaded programming on *nix for a long time so this may be out of date or I may be remembering wrongly, plus some googling filled in bits) :-
You should really use -pthread rather than -lpthread as as well as including the library it also sets any other options (which usually on linux means setting -D_REENTRANT as well). So yes, if you use -lpthread then you need -D_REENTRANT otherwise things could go wrong.
You can ask a thread to cancel with pthread_cancel(threadID); It should then stop at the next cancel point. I think threads default to delayed cancelling, though a thread can set it's cancel type to asynchronous (will be cancelled without waiting for a cancel point) with pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &previousCancelType);. You'll need to make sure the thread (and/or parent thread) knows how to clean up properly.
You can request changing priority with pthread_setschedprio(threadID, priority); Exactly what values to use for priority depends on the scheduling policy.
You should really use -pthread rather than -lpthread as as well as including the library it also sets any other options (which usually on linux means setting -D_REENTRANT as well). So yes, if you use -lpthread then you need -D_REENTRANT otherwise things could go wrong.
You can ask a thread to cancel with pthread_cancel(threadID); It should then stop at the next cancel point. I think threads default to delayed cancelling, though a thread can set it's cancel type to asynchronous (will be cancelled without waiting for a cancel point) with pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &previousCancelType);. You'll need to make sure the thread (and/or parent thread) knows how to clean up properly.
You can request changing priority with pthread_setschedprio(threadID, priority); Exactly what values to use for priority depends on the scheduling policy.
She who travels light — forgot something.
Please note that my name doesn't start with the @ character so can people please stop writing it as if it does!
Please note that my name doesn't start with the @ character so can people please stop writing it as if it does!
Re: pthread questions
thank you, Paeryn, that was very helpful, especially about -pthread and -lpthread.
The other references are more complicated than I expected them to be but at least give me a guidance to keywords I have to look at more closely, maybe I will then see more clear. Finally for me as a former programmer for bytecode to VMs (edit, and for Arduinos) it's not just about missing (overcomplicated, messed up) Linux detailes but also simple missing English language knowledge (where Goggle translate is additionally messing all things up).
VMs (edit, and the Arduinos IDE) always finally were handling all the complicated underlaying stuff so I could focus on my own algorithms, now I have to rewrite the whole operating system before, as it seems.
e.g., for the first elementary step into this maze: what is threadID ?
So far I just have
pthread_t thread1, thread2, thread2;
pthread_create(&thread1, NULL, thread2Go, NULL);
pthread_create(&thread2, NULL, thread3Go, NULL);
pthread_create(&thread3, NULL, thread4Go, NULL);
which of these items is the thread ID I have to pass to pthread_cancel ?
The other references are more complicated than I expected them to be but at least give me a guidance to keywords I have to look at more closely, maybe I will then see more clear. Finally for me as a former programmer for bytecode to VMs (edit, and for Arduinos) it's not just about missing (overcomplicated, messed up) Linux detailes but also simple missing English language knowledge (where Goggle translate is additionally messing all things up).
VMs (edit, and the Arduinos IDE) always finally were handling all the complicated underlaying stuff so I could focus on my own algorithms, now I have to rewrite the whole operating system before, as it seems.
e.g., for the first elementary step into this maze: what is threadID ?
So far I just have
pthread_t thread1, thread2, thread2;
pthread_create(&thread1, NULL, thread2Go, NULL);
pthread_create(&thread2, NULL, thread3Go, NULL);
pthread_create(&thread3, NULL, thread4Go, NULL);
which of these items is the thread ID I have to pass to pthread_cancel ?
Last edited by davenull on Sun Nov 08, 2015 9:01 am, edited 1 time in total.
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
Re: pthread questions
Code: Select all
int pthread_cancel(pthread_t thread);
Re: pthread questions
excellent, now I can start working with this information!
many thanks, Andy, and again, also to Paeryn!
many thanks, Andy, and again, also to Paeryn!
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
Re: pthread questions
hey,
I'm trying to handle pthread now for higher priority tasks.
Given I have a program starting 3 pthread tasks, and the first one should run continuously by a higher priority than all the others to be capable of a better "real-time" performance, I now am starting with this code:
Task1 should become a higher priority, as I need to mimic a quite (!) reliable 100µs loop time performance to poll GPIO pins repetitively, both against internal pthread tasks and as well against possibly most all other currently running user space tasks/demons/whatever.
As I am a complete beginner to pthread, my questions are:
- is my approach correct?
- at which priority level are tasks running by default?
- which value for priority should a choose for task1?
- is there anything else to add to the code?
I'm running this code on a Raspi 2B.
I'm trying to handle pthread now for higher priority tasks.
Given I have a program starting 3 pthread tasks, and the first one should run continuously by a higher priority than all the others to be capable of a better "real-time" performance, I now am starting with this code:
Code: Select all
#include <stdio.h>
#include <pthread.h>
#include <wiringPi.h>
//...
void* thread1Name(void *)
{
while(1) {
///... (code/loop)
delayMicroseconds(100);
}
return NULL;
}
void* thread2Name(void *)
{
while(1) {
///... (code/loop)
delay(10);
}
return NULL;
}
void* thread3Name(void *)
{
while(1) {
///... (code/loop)
delay(1);
}
return NULL;
}
task main() {
//create the threads
pthread_t thread1ID, thread2ID, thread3ID;
pthread_create(&thread1ID, NULL, thread1Name, NULL);
pthread_create(&thread2ID, NULL, thread2Name, NULL);
pthread_create(&thread3ID, NULL, thread3Name, NULL);
int priority=1; // <<<<<<<<<<<< ??? which value for high priority ? 1? 2? 3?...?
pthread_setschedprio(thread1ID, priority);
//wait for threads to join before exiting
pthread_join(thread1ID, NULL);
pthread_join(thread2ID, NULL);
pthread_join(thread3ID, NULL);
return 0;
}
Task1 should become a higher priority, as I need to mimic a quite (!) reliable 100µs loop time performance to poll GPIO pins repetitively, both against internal pthread tasks and as well against possibly most all other currently running user space tasks/demons/whatever.
As I am a complete beginner to pthread, my questions are:
- is my approach correct?
- at which priority level are tasks running by default?
- which value for priority should a choose for task1?
- is there anything else to add to the code?
I'm running this code on a Raspi 2B.
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
Re: pthread questions
thank you, I already read this, I have googled all and everything I could finde - but everything I read is far too sophisticated and I understand not a single word ( also attributable to by poor English skills).
So I need just 1 practical source code about my code above and how to make it correct (anyway, I'm not sure that it will work even on the quadacore in order to achieve a better real-time capability though) -
So I need just 1 practical source code about my code above and how to make it correct (anyway, I'm not sure that it will work even on the quadacore in order to achieve a better real-time capability though) -
Task1 should become a higher priority, as I need to mimic a quite (!) reliable 100µs loop time performance to poll GPIO pins repetitively, both against internal pthread tasks and as well against possibly most all other currently running user space tasks/demons/whatever.
As I am a complete beginner to pthread, my questions are:
- is my approach correct?
- at which priority level are tasks running by default?
- which value for priority should a choose for task1?
- is there anything else to add to the code?
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
Re: pthread questions
I think the answer is, that it is complicated. If I am reading the output of "chrt -m" correctly, it would appear that you can only change a threads priority if you set the scheduling policy to either SCHED_FIFO or SCHED_RR. Otherwise the minimum and maximum priorities are zero.
Code: Select all
% chrt -m
SCHED_OTHER min/max priority : 0/0
SCHED_FIFO min/max priority : 1/99
SCHED_RR min/max priority : 1/99
SCHED_BATCH min/max priority : 0/0
SCHED_IDLE min/max priority : 0/0
Re: pthread questions
IIRC, Gordon Henderson was doing a similar thing to his WiringPi libs, by running the thread to poll GPIOs by a higher priority task.
But I don't only have to poll pins quickly, I also have to process them even as quickly as possible, instantaneously, without delay.
As I'm completely new to Linux and pthread, but common user space tasks are definitvely too slow and too untrustworthy, and because the Raspi does not provide hardware-timer-Interrupts- what should I do best?
I have no idea about scheduling policies, but I am afraid it would not be as easy to do as by OSEK RTOS where one can simply specify task priorities in the related .oil files.
So Linux is really a torture if one needs quick real-time capabilities by reliable 100µs clock beats.
Anyway, as I am not able to figure that out:
Who is experienced in higher priority threading, establishing:
a 100µs thread (+/- 30%),
don't yield,
to poll (at least) 8 GPIOs (for rotary encoders) safely,
still don't yield,
acquire a mutex,
still don't yield,
process the 8 values to calculate the curent encoder position upadtes of (at least) 4 rotary encoders,
don't yield in between,
when finished:
release that mutex,
and only when processed everything and when completely finished
- then yield to the next time slice.
But during the round-robin:
safely re-awaken when another 100µs have passed,
when necessary force the current timeslice to yield prematurely,
in order to do the next high priority processing loop.
This is actually what an Arduino Due does when a ARM DueTimer Interrupt has been established (or even AVRs by AVR Timer Interrupts).
But I don't only have to poll pins quickly, I also have to process them even as quickly as possible, instantaneously, without delay.
As I'm completely new to Linux and pthread, but common user space tasks are definitvely too slow and too untrustworthy, and because the Raspi does not provide hardware-timer-Interrupts- what should I do best?
I have no idea about scheduling policies, but I am afraid it would not be as easy to do as by OSEK RTOS where one can simply specify task priorities in the related .oil files.
So Linux is really a torture if one needs quick real-time capabilities by reliable 100µs clock beats.
Anyway, as I am not able to figure that out:
Who is experienced in higher priority threading, establishing:
a 100µs thread (+/- 30%),
don't yield,
to poll (at least) 8 GPIOs (for rotary encoders) safely,
still don't yield,
acquire a mutex,
still don't yield,
process the 8 values to calculate the curent encoder position upadtes of (at least) 4 rotary encoders,
don't yield in between,
when finished:
release that mutex,
and only when processed everything and when completely finished
- then yield to the next time slice.
But during the round-robin:
safely re-awaken when another 100µs have passed,
when necessary force the current timeslice to yield prematurely,
in order to do the next high priority processing loop.
This is actually what an Arduino Due does when a ARM DueTimer Interrupt has been established (or even AVRs by AVR Timer Interrupts).
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
Re: pthread questions
Gordon basically uses the following:
within a thread. This sets the scheduling policy to Round Robin and sets the priority of the thread to the maximum priority for the Round Robin policy.
In your example ...
Code: Select all
struct sched_param param;
param.sched_priority = sched_get_priority_max(SCHED_RR);
pthread_setschedparam(pthread_self(), SCHED_RR, ¶m);
In your example ...
Code: Select all
struct sched_param param;
param.sched_priority = sched_get_priority_max(SCHED_RR);
pthread_setschedparam(thread1ID, SCHED_RR, ¶m);
Re: pthread questions
that looks very promising , thank you Andy!
Just 1 thing:
where have I to put these lines exactly?
In task main(), directly before starting/declaring task thread1Name(),
or In task main() immediatly after declaring thread1Name(),
or (most unlikely, but who knows) -: inside / alt the start of the task thread1Name() itself, perhaps before the endless loops is started?
and then the rest of the declarations and implementations for the remaining tasks can be kept as it is?
Just 1 thing:
where have I to put these lines exactly?
In task main(), directly before starting/declaring task thread1Name(),
or In task main() immediatly after declaring thread1Name(),
or (most unlikely, but who knows) -: inside / alt the start of the task thread1Name() itself, perhaps before the endless loops is started?
and then the rest of the declarations and implementations for the remaining tasks can be kept as it is?
Code: Select all
#include <stdio.h>
#include <pthread.h>
#include <wiringPi.h>
//...
void* thread1Name(void *)
{
while(1) {
///... (code/loop)
delayMicroseconds(100);
}
return NULL;
}
void* thread2Name(void *)
{
while(1) {
///... (code/loop)
delay(10);
}
return NULL;
}
void* thread3Name(void *)
{
while(1) {
///... (code/loop)
delay(1);
}
return NULL;
}
task main() {
// declare the threads
pthread_t thread1ID, thread2ID, thread3ID;
//create the threads
pthread_create(&thread1ID, NULL, thread1Name, NULL);
pthread_create(&thread2ID, NULL, thread2Name, NULL);
pthread_create(&thread3ID, NULL, thread3Name, NULL);
//wait for threads to join before exiting
pthread_join(thread1ID, NULL);
pthread_join(thread2ID, NULL);
pthread_join(thread3ID, NULL);
return 0;
}
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
Re: pthread questions
Yes. If you want your thread to wake up every 100µs, then that does not leave enough time asleep for the kernel to reprogram the memory management unit and schedule another task for long enough to do anything useful. The real time thread is going to hog an entire core, so you had better be using a Pi2.davenull wrote:So Linux is really a torture if one needs quick real-time capabilities by reliable 100µs clock beats.
To get 20000 context switches per second you would need a real time operating system with simpler memory protection, or better still, use interrupts. The Pi does have programmable timer interrupts (I do not know how fast they go) and GPIO change interrupts. But interrupts need to be handled in kernel memory, and kernel internals are sparsely documented, so writing a kernel module is not a good option for you.
What are you actually doing with the rotary encoder positions, once you have calculated them? If you did not need such low latency then a better option might be to sample the GPIOs continuously using the DMA engine via pigpio, and process the data in chunks.But I don't only have to poll pins quickly, I also have to process them even as quickly as possible, instantaneously, without delay.
Re: pthread questions
1st, Im using the Pi 2B quadcore - for a single core it's perhaps even more unsolvable.
2nd, I'm using the encoders for odometry of an autonomous vehicle/robot, and for PID controls of a robot arm control (move to encoder target, start and brake smoothly, don't stall close to the target, don't overshoot).
So once the pin signal edges (2x2=4 pin changes up/down) have been detected and the encoder values have been counted and added/subtracted correctly without dropping counts (at every ~100- up to 200µs), then the evaluation for odometry and PID control is working fine at 1-2ms tasks - provided that the encoder value has been processed correctly before.
Till now I tried 2 options which did NOT work:
- Gordon Henderson provided a code example using WiringPi for 1 single pinchange event (just 1 pin of 2 at pin_up), but by that I only get 1/4 resolution, that's too poor.
- Using all 4 pinchanges instead for pinchange interrupts (pin A up/dn, pin B up/down) and that for all 4 rotary encoders it calls this routine far too often and so it drops repetitively 1/5 of all encoder ticks (getting just 300 ticks for 360 degrees instead of, you might have guessed it: 360 ticks).
So pinchange IRQs for 4x4=16 pinchange events is not a good choice.
Instead, Timer IRQs at 100µs (+/-) are fine: enough time to make sort of a "flash-light foto" of all 16 pinstates and then calculating the changes by current pin levels!
That works fine on all my Arduinos, not just AVRs but also my ARMs (Due, and even Zero).
The code is very common and works on my Arduinos even for 8 motors = 32 pinchange edges: on a Arduino Mega in 200µs loops.
This is the ISR task (taken from my Arduino Due code controlling 6 motors):
2nd, I'm using the encoders for odometry of an autonomous vehicle/robot, and for PID controls of a robot arm control (move to encoder target, start and brake smoothly, don't stall close to the target, don't overshoot).
So once the pin signal edges (2x2=4 pin changes up/down) have been detected and the encoder values have been counted and added/subtracted correctly without dropping counts (at every ~100- up to 200µs), then the evaluation for odometry and PID control is working fine at 1-2ms tasks - provided that the encoder value has been processed correctly before.
Till now I tried 2 options which did NOT work:
- Gordon Henderson provided a code example using WiringPi for 1 single pinchange event (just 1 pin of 2 at pin_up), but by that I only get 1/4 resolution, that's too poor.
- Using all 4 pinchanges instead for pinchange interrupts (pin A up/dn, pin B up/down) and that for all 4 rotary encoders it calls this routine far too often and so it drops repetitively 1/5 of all encoder ticks (getting just 300 ticks for 360 degrees instead of, you might have guessed it: 360 ticks).
So pinchange IRQs for 4x4=16 pinchange events is not a good choice.
Instead, Timer IRQs at 100µs (+/-) are fine: enough time to make sort of a "flash-light foto" of all 16 pinstates and then calculating the changes by current pin levels!
That works fine on all my Arduinos, not just AVRs but also my ARMs (Due, and even Zero).
The code is very common and works on my Arduinos even for 8 motors = 32 pinchange edges: on a Arduino Mega in 200µs loops.
This is the ISR task (taken from my Arduino Due code controlling 6 motors):
Code: Select all
/*************************************************************
* Interrupt Handler Routine
*************************************************************/
void encHandler() {
ISRab [ 0] <<= 2;
ISRab [ 0] &= B00001100;
ISRab [ 0] |= (digitalRead(pinenc0A) << 1) | digitalRead(pinenc0B);
motenc[ 0] += schrittTab[ISRab[0]]; //
ISRab [ 1] <<= 2;
ISRab [ 1] &= B00001100;
ISRab [ 1] |= (digitalRead(pinenc1A) << 1) | digitalRead(pinenc1B);
motenc[ 1] += schrittTab[ISRab[1]]; //
ISRab [ 2] <<= 2;
ISRab [ 2] &= B00001100;
ISRab [ 2] |= (digitalRead(pinenc2A) << 1) | digitalRead(pinenc2B);
motenc[ 2] += schrittTab[ISRab[2]]; //
ISRab [ 3] <<= 2;
ISRab [ 3] &= B00001100;
ISRab [ 3] |= (digitalRead(pinenc3A) << 1) | digitalRead(pinenc3B);
motenc[ 3] += schrittTab[ISRab[3]]; //
ISRab [ 4] <<= 2;
ISRab [ 4] &= B00001100;
ISRab [ 4] |= (digitalRead(pinenc4A) << 1) | digitalRead(pinenc4B);
motenc[ 4] += schrittTab[ISRab[4]]; //
ISRab [ 5] <<= 2;
ISRab [ 5] &= B00001100;
ISRab [ 5] |= (digitalRead(pinenc5A) << 1) | digitalRead(pinenc5B);
motenc[ 5] += schrittTab[ISRab[5]]; //
}
Last edited by davenull on Mon Jan 04, 2016 2:30 pm, edited 1 time in total.
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
Re: pthread questions
but I would prefer to try Andy's suggestion now, so just for my understanding:
davenull wrote:that looks very promising , thank you Andy!AndyD wrote:In your example ...
Code: Select all
struct sched_param param; param.sched_priority = sched_get_priority_max(SCHED_RR); pthread_setschedparam(thread1ID, SCHED_RR, ¶m);
Just 1 thing:
where have I to put these lines exactly?
In task main(), directly before starting/declaring task thread1Name(),
or In task main() immediatly after declaring thread1Name(),
or (most unlikely, but who knows) -: inside / at the start of the task thread1Name() itself, perhaps before the endless loop is started?
and then the rest of the declarations and implementations for the remaining tasks can be kept as it is?
Code: Select all
#include <stdio.h> #include <pthread.h> #include <wiringPi.h> //... void* thread1Name(void *) { while(1) { ///... (code/loop) delayMicroseconds(100); } return NULL; } void* thread2Name(void *) { while(1) { ///... (code/loop) delay(10); } return NULL; } void* thread3Name(void *) { while(1) { ///... (code/loop) delay(1); } return NULL; } task main() { // declare the threads pthread_t thread1ID, thread2ID, thread3ID; //create the threads pthread_create(&thread1ID, NULL, thread1Name, NULL); pthread_create(&thread2ID, NULL, thread2Name, NULL); pthread_create(&thread3ID, NULL, thread3Name, NULL); //wait for threads to join before exiting pthread_join(thread1ID, NULL); pthread_join(thread2ID, NULL); pthread_join(thread3ID, NULL); return 0; }
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;int main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PointOut(x,y);}}}for(;;);}