FreeRTOS freezes - c

I have a simple FreeRTOS programm and basically I need to calculate the time it takes to run for a different number of iterations.
The problem is that it just freezes and doesn't execute anymore though the iterations are not complete yet and I need it to succesfully come to vTaskEndScheduler() to terminate so I can calculate the time correctly. What could be a reason?
Freeze screenshot
void Task1() {
for (int i = 0; i < 100; i++)
{
printf("This is task 1 ");
printf("Iteration number ");
printf("%d", i);
printf("\n");
vTaskDelay(100);
}
vTaskEndScheduler();
};
void Task2() {
for (int i = 0; i < 100; i++) {
printf("This is task 2 ");
printf("Iteration number ");
printf("%d", i);
printf("\n");
vTaskDelay(100);
}
vTaskEndScheduler();
};
void main_blinky(void)
{
enableFlushAfterPrintf();
xTaskCreate(Task1, (signed char*) "t1", 100, NULL, 1, NULL);
xTaskCreate(Task2, (signed char*) "t2", 100, NULL, 1, NULL);
vTaskStartScheduler();
}

Just at a glance, without knowing anything about your system, I would GUESS printf() is causing the problem. How is it implemented? Is it thread safe? Do your tasks have enough stack space for its stack requirements, which can be substantial depending on the library you are using: https://freertos.org/Stacks-and-stack-overflow-checking.html
See notes in the (free but somewhat out of date) book (https://freertos.org/Documentation/RTOS_book.html) ref printf.

You must first choose appropriate stack for task and to be sure it's accessible by heap size in run-time, after that then i think
problem may is in printf() method and the way that's implemented.

Related

I don't know what is causing a segmentation fault

I am trying to create a simple "diary", where you add workers and then write them how many hours they have worked. But every time I get to the switch statement, I get a segmentation fault. I don't know what is causing it and my knowledge is not yet on the level where I can find it myself.
The code:
include <stdio.h>
include <stdlib.h>
include <string.h>
int vybera(int pocet){
int vyber;
int i;
printf("\nKtery zamestnanec?\n");
for(i = 0; i < pocet; i++){
printf("%d\n", i + 1);
}
scanf("%d", vyber);
return vyber;
}
int main(int argc, char** argv) {
int worker;
int pocet;
int i;
int vyber;
int pomoc;
int odprac = 0;
printf("Kolik zamestnancu chcete pridat: ");
scanf("%d%*c", &pocet);
char workforce[pocet][100];
printf("Zadejte %d jmen: \n", pocet);
for(i = 0; i < pocet; i++){
gets(workforce[i]);
}
for(i = 0; i < pocet; i++){
printf("%s\n", workforce[i]);
}
vyber = vybera(pocet);
switch(vyber){
case 1:
worker = vyber - 1;
printf("Vybrali jste %s.\n", workforce[worker]);
printf("Pocet odprac. hodin: ");
scanf("%d", pomoc);
odprac += pomoc;
strcat(workforce[worker], (", %c", odprac + '0'));
break;
case 2:
worker = vyber - 1;
printf("Vybrali jste %s.\n", workforce[worker]);
printf("Pocet odprac. hodin: ");
scanf("%d", pomoc);
odprac += pomoc;
strcat(workforce[worker], (", %c", odprac + '0'));
break;
case 3:
worker = vyber - 1;
printf("Vybrali jste %s.\n", workforce[worker]);
printf("Pocet odprac. hodin: ");
scanf("%d", pomoc);
odprac += pomoc;
strcat(workforce[worker], (", %c", odprac + '0'));
break;
case 4:
worker = vyber - 1;
printf("Vybrali jste %s.\n", workforce[worker]);
printf("Pocet odprac. hodin: ");
scanf("%d", pomoc);
odprac += pomoc;
strcat(workforce[worker], (", %c", odprac + '0'));
break;
case 5:
worker = vyber - 1;
printf("Vybrali jste %s.\n", workforce[worker]);
printf("Pocet odprac. hodin: ");
scanf("%d", pomoc);
odprac += pomoc;
strcat(workforce[worker], (", %c", odprac + '0'));
break;
default:
printf("Spatny vyber.\n");
}
for(i = 0; i < pocet; i++){
printf("%s\n", workforce[i]);
}
return (EXIT_SUCCESS);
}
I am really at my wits end, and need every help I can get. The reason why I'm posting this even though there are many question on the segementation fault topic is that none of them are using my code. I appreciate any help and all of your patience.
EDIT: I'm from Czechia, hence why most of my variables and all my printf outputs are in czech. Just FYI.
change: scanf("%d", vyber); to scanf("%d", &vyber) do the same with pomoc;
Explanation: Because vyber variable is int you need to explicitly pass the address value with "&" ampersand, unlike a string(which implicitly passes its address). The segmentation fault indicates you are trying to access a memory which doesn't belong to you. In this case vyber.
You've already been told where the problem is, but let me briefly mention how you can find the (next) problem yourself. Basically, there are (at least) three ways:
Use a debugger to run your program line by line until it crashes. A debugger will also let you stop the program and examine the values of any variables to see what the code is actually doing.
You haven't told us what OS, compiler and IDE (if any) you're using, so I can't recommend any specific debugger (and in any case that's really not on-topic for SO), but there almost certainly is a debugger available for your system, whatever it is. Learning how to use a debugger takes a little effort, but it's definitely worth it.
If you can't or don't want to use a debugger for some reason, you can do "poor man's debugging" by adding printf() statements into your code that show what's happening. That way, you can see how far the program gets before crashing, and you can also print out the values of variables to get a better idea of what's happening.
I would recommend printing to the standard error stream (with fprintf(stderr, "...")), since it won't interfere with normal output of the program, and since the error stream will be automatically flushed every time you print to it, so that there's no risk of buffered output being lost if the program crashes.
A useful trick is to prefix such debugging print statements with if (DEBUG), like this:
if (DEBUG) fprintf(stderr, "This is an example of debugging output.\n");
Then, at the top of your program, include a line like:
#define DEBUG 1
That way, you can easily turn the debugging output off by changing the 1 to a 0. (There are also more advanced ways to change the definition at compile time, or to configure your IDE to change it depending on the build target, but that's outside the scope of the answer.)
Finally, you can do "bisection debugging". Basically, make a copy of your program (or, better yet, commit it into your version control system) and start removing parts of the code until the problem stops happening. At that point, you'll know that the problem is related to something in the last piece of code you removed. You can then undo the most recent change, and remove something else, and keep doing that until you've reduced your program to the simplest possible example that still demonstrates the problem.
At that point, it should be easy to see what the problem is, since you no longer have any irrelevant code left to distract you. Or, if not, at least you have a short piece of code that cleanly demonstrates the problem and which you can post on Stack Overflow to ask for help. :)
scanf("%d", pomoc);
This is incorrect syntax for the scanf() function. It should be:
scanf("%d", &pomoc);
This same error is replicated in the input statement for vyber
scanf("%d", &vyber)
This happens because you are trying to access an out-of bounds location in memory with the scanf() function. Since you don't reference the variable vyber and pomoc, the compiler tries to access the memory spot at an address equal to the variable stored in vyber and pomoc, rather than the memory location of these respective variables. This goes into undefined behavior, which is why you get a seg-fault.

How to pass a sequential counter by reference to pthread start routine?

Below is my C code to print an increasing global counter, one increment per thread.
#include <stdio.h>
#include <pthread.h>
static pthread_mutex_t pt_lock = PTHREAD_MUTEX_INITIALIZER;
int count = 0;
int *printnum(int *num) {
pthread_mutex_lock(&pt_lock);
printf("thread:%d ", *num);
pthread_mutex_unlock(&pt_lock);
return NULL;
}
int main() {
int i, *ret;
pthread_t pta[10];
for(i = 0; i < 10; i++) {
pthread_mutex_lock(&pt_lock);
count++;
pthread_mutex_unlock(&pt_lock);
pthread_create(&pta[i], NULL, (void *(*)(void *))printnum, &count);
}
for(i = 0; i < 10; i++) {
pthread_join(pta[i], (void **)&ret);
}
}
I want each thread to print one increment of the global counter but they miss increments and sometimes access same values of global counter from two threads. How can I make threads access the global counter sequentially?
Sample Output:
thread:2
thread:3
thread:5
thread:6
thread:7
thread:7
thread:8
thread:9
thread:10
thread:10
Edit
Blue Moon's answer solves this question. Alternative approach is available in MartinJames'es comment.
A simple-but-useless approach is to ensure thread1 prints 1, thread2 prints 2 and so on is to put join the thread immmediately:
pthread_create(&pta[i], NULL, printnum, &count);
pthread_join(pta[i], (void **)&ret);
But this totally defeats the purpose of multi-threading because only one can make any progress at a time.
Note that I removed the superfluous casts and also the thread function takes a void * argument.
A saner approach would be to pass the loop counter i by value so that each thread would print different value and you would see threading in action i.e. the numbers 1-10 could be printed in any order and also each thread would print a unique value.

Informative "if" statement in "for" loop

Normally when I have a big for loop I put messages to inform me in which part of the process my program is, for example:
for(i = 0; i < large_n; i++) {
if( i % (large_n)/1000 == 0) {
printf("We are at %ld \n", i);
}
// Do some other stuff
}
I was wondering if this hurts too much the performance (a priori) and if it is the case if there is a smarter alternative.Thanks in advance.
Maybe you can split the large loop in order to check the condition sometimes only, but I don't know if this will really save time, that depends more on your "other stuff".
int T = ...; // times to check the condition, make sure large_n % T == 0
for(int t = 0; t < T; ++t)
{
for(int i = large_n/T * t; i < large_n/T * (t+1); ++i)
{
// other stuff
}
printf("We are at %ld \n", large_n/T * (t+1));
}
Regardless of what is in your loop, I wouldn't be leaving statements like printf in unless it's essential to the application/user, nor would I use what are effectively redundant if statements, for the same reason.
Both of these are examples of trace level debugging. They're totally valid and in some cases very useful, but generally not ultimately so in the end application. In this respect, a usual thing to do is to only include them in the build when you actually want to use the information they provide. In this case, you might do something like this:
#define DEBUG
for(i = 0; i < large_n; i++)
{
#ifdef DEBUG
if( i % (large_n)/1000 == 0)
{
printf("We are at %ld \n", i);
}
#endif
}
Regarding the performance cost of including these debug outputs all the time, it will totally depend on the system you're running, the efficiency of whatever "printing" statement you're using to output the data, the check/s you're performing and, of course, how often you're trying to perform output.
Your mod test probably doesn't hurt performance but if you want a very quick test and you're prepared for multiples of two then consider a mathematical and test:
if ( ( i & 0xFF ) == 0 ) {
/* this gets printed every 256 iterations */
...
}
or
if ( ( i & 0xFFFF ) == 0 ) {
/* this gets printed every 65536 iterations */
...
}
By placing a print statement inside of the for loop, you are sacrificing some performance.
Because the program needs to do a system call to write output to the screen every time the message is printed, it takes CPU time away from the program itself.
You can see the difference in performance between these two loops:
int i;
printf("Start Loop A\n");
for(i = 0; i < 100000; i++) {
printf("%d ", i);
}
printf("Done with Loop A\n");
printf("Start Loop B\n");
for(i = 0; i < 100000; i++) {
// Do Nothing
}
printf("Done with Loop B\n");
I would include timing code, but I am in the middle of work and can update it later over lunch.
If the difference isn't noticeable, you can increase 100000 to a larger number (although too large a number would cause the first loop to take WAY too long to complete).
Whoops, forgot to finish my answer.
To cut down on the number of system calls your program needs to make, you could check a condition first, and only print if that condition is true.
For example, if you were counting up as in my example code, you could only print out every 100th number by using %:
int i;
for(i = 0; i < 100000; i++) {
if(i%100 == 0)
printf("%d", i);
}
That will reduce the number of syscalls from ~100000 to ~1000, which in turn would increase the performance of the loop.
The problem is IO operation printf takes a much time than processor calculates. you can reduce the time if you can add them all and print finally.
Notation:
Tp = total time spent executing the progress statements.
Tn = total time spent doing the other normal stuff.
>> = Much greater than
If performance is your main criteria, you want Tn >> Tp. This strongly suggests that the code should be profiled so that you can pick appropriate values. The routine 'printf()' is considered a slow routine (much slower than %) and is a blocking routine (that is, the thread that calls it may pend waiting for a resource used by it).
Personally, I like to abstract away the progress indicator. It can be a logging mechanism,
a printf, a progress box, .... Heck, it may be updating a structure that is read by another thread/task/process.
id = progressRegister (<some predefined type of progress update mechanism>);
for(i = 0; i < large_n; i++) {
progressUpdate (id, <string>, i, large_n);
// Do some other stuff
}
progressUnregister(id);
Yes, there is some overhead in calling the routine 'progressUpdate()' on each iteration, but again, as long as Tn >> Tp, it usually is not that important.
Hope this helps.

How to change the count of a pthread_barrier?

The problem is that we have to implement a kind of "running-contest" using pthreads. After one track we have to wait until all runners/threads are done until this point, so we use a barrier for that.
But now we also have to implement the probability of injuries. So we wrote a function, which sometimes reduces the number of runners, and reinitialize the barrier with a smaller count. Now the problem is that the program is not always terminating. I guess the reason for this is that some of the threads have already been at the barrier, and after reinitializing them the required amount is not arriving.
The code for the simulation of the injury looks like this:
void simulateInjury(int number) {
int totalRunners = 0;
int i = 0;
if (rand() % 10 < 1) {
printf("Runner of Team %i injured!\n", number);
pthread_mutex_lock(&evaluate_teamsize);
standings.teamSize[number]--;
for (i = 0; i < teams; i++) {
totalRunners += standings.teamSize[i];
}
pthread_barrier_destroy(&barrier_track1);
pthread_barrier_destroy(&barrier_track4[number]);
pthread_barrier_init(&barrier_track1, NULL, totalRunners);
pthread_barrier_init(&barrier_track4[number], NULL, standings.teamSize[number]);
pthread_mutex_unlock(&evaluate_teamsize);
pthread_exit(NULL);
}
}
Or is there maybe a way to just change the count argument of the barrier?
I see two errors:
You should not re-initialize a barrier while some thread is using
it.
You should not execute the re-initialization of the barrier
simultaneously by several threads.
For the first you can create a second barrier that you use in alternation with the first.
For the second you should use the return value of the wait function to designate one particular thread that will do the re-initialization.

Seg Fault when initializing array

I'm taking a class on C, and running into a segmentation fault. From what I understand, seg faults are supposed to occur when you're accessing memory that hasn't been allocated, or otherwise outside the bounds. 'Course all I'm trying to do is initialize an array (though rather large at that)
Am I simply misunderstanding how to parse a 2d array? Misplacing a bound is exactly what would cause a seg fault-- am I wrong in using a nested for-loop for this?
The professor provided the clock functions, so I'm hoping that's not the problem. I'm running this code in Cygwin, could that be the problem? Source code follows. Using c99 standard as well.
To be perfectly clear: I am looking for help understanding (and eventually fixing) the reason my code produces a seg fault.
#include <stdio.h>
#include <time.h>
int main(void){
//first define the array and two doubles to count elapsed seconds.
double rowMajor, colMajor;
rowMajor = colMajor = 0;
int majorArray [1000][1000] = {};
clock_t start, end;
//set it up to perform the test 100 times.
for(int k = 0; k<10; k++)
{
start=clock();
//first we do row major
for(int i = 0; i < 1000; i++)
{
for(int j = 0; j<1000; j++)
{
majorArray[i][j] = 314;
}
}
end=clock();
rowMajor+= (end-start)/(double)CLOCKS_PER_SEC;
//at this point, we've only done rowMajor, so elapsed = rowMajor
start=clock();
//now we do column major
for(int i = 0; i < 1000; i++)
{
for(int j = 0; j<1000; j++)
{
majorArray[j][i] = 314;
}
}
end=clock();
colMajor += (end-start)/(double)CLOCKS_PER_SEC;
}
//now that we've done the calculations 100 times, we can compare the values.
printf("Row major took %f seconds\n", rowMajor);
printf("Column major took %f seconds\n", colMajor);
if(rowMajor<colMajor)
{
printf("Row major is faster\n");
}
else
{
printf("Column major is faster\n");
}
return 0;
}
Your program works correctly on my computer (x86-64/Linux) so I suspect you're running into a system-specific limit on the size of the call stack. I don't know how much stack you get on Cygwin, but your array is 4,000,000 bytes (with 32-bit int) - that could easily be too big.
Try moving the declaration of majorArray out of main (put it right after the #includes) -- then it will be a global variable, which comes from a different allocation pool that can be much bigger.
By the way, this comparison is backwards:
if(rowMajor>colMajor)
{
printf("Row major is faster\n");
}
else
{
printf("Column major is faster\n");
}
Also, to do a test like this you really ought to repeat the process for many different array sizes and shapes.
You are trying to grab 1000 * 1000 * sizeof( int ) bytes on the stack. This is more then your OS allows for the stack growth. If on any Unix - check the ulimit -a for max stack size of the process.
As a rule of thumb - allocate big structures on the heap with malloc(3). Or use static arrays - outside of scope of any function.
In this case, you can replace the declaration of majorArray with:
int (*majorArray)[1000] = calloc(1000, sizeof majorArray);
I was unable to find any error in your code, so I compiled it and run it and worked as expected.
You have, however, a semantic error in your code:
start=clock();
//set it up to perform the test 100 times.
for(int k = 0; k<10; k++)
{
Should be:
//set it up to perform the test 100 times.
for(int k = 0; k<10; k++)
{
start=clock();
Also, the condition at the end should be changed to its inverse:
if(rowMajor<colMajor)
Finally, to avoid the problem of the os-specific stack size others mentioned, you should define your matrix outside main():
#include <stdio.h>
#include <time.h>
int majorArray [1000][1000];
int main(void){
//first define the array and two doubles to count elapsed seconds.
double rowMajor, colMajor;
rowMajor = colMajor = 0;
This code runs fine for me under Linux and I can't see anything obviously wrong about it. You can try to debug it via gdb. Compile it like this:
gcc -g -o testcode test.c
and then say
gdb ./testcode
and in gdb say run
If it crashes, say where and gdb tells you, where the crash occurred. Then you now in which line the error is.
The program is working perfectly when compiled by gcc, & run in Linux, Cygwin may very well be your problem here.
If it runs correctly elsewhere, you're most likely trying to grab more stack space than the OS allows. You're allocating 4MB on the stack (1 mill integers), which is way too much for allocating "safely" on the stack. malloc() and free() are your best bets here.

Resources