C static variable not updating - c

I'm having a problem with my C code where I declare a static int variable (as a flag), then initialize it to -1 in init() which is only called once, then when I try to update the value to 0 or 1 later on, it keeps reverting back to -1.
Does anyone know what the problem can be?
I don't have any local variables with the same identifier so I'm really lost.
Thanks!
static int previousState;
void init()
{
previousState = -1;
}
void moveForward(int currentState)
{
if (previousState == -1)
previousState = currentState;
if (previousState != currentState)
{
/* do stuff */
/* PROBLEM: it never goes into here, because previousState is always -1! */
}
/* other code */
}
void main()
{
init();
if (fork() == 0)
{
/* do stuff */
moveForward(1);
exit();
}
/* more forks */
moveForward(0);
exit();
}

Each process calls moveForward just once. Processes do not share static data!
Use threads, or use shared memory. Also use mutex or semaphore for concurrent access of shared data . Preferably switch to a language better suited for parallel prosessing...

Related

proper way to create multiple forked threads

I'm creating a timer function for a bit of embedded code that will allow me to bypass certain GPIO checks while a certain process is running, i.e., when the timer is running in a non-blocking manner.
This seems to run just fine the first 11 times the operations occur, but every time, on the 11th iteration the system will crash. The likely culprit is something in how the timer thread is being handled. My guess is there's some bit of memory cleanup that I'm not handling properly and that's leading to memory leaks of some kind. But I'm really not sure.
I can see through debug tracing that the thread is exiting after each iteration.
Here is the timer code:
#include <time.h>
#include <semaphore.h>
#include <pthread.h>
#include <msp432e4_timer.h>
extern void TaskSleep(uint32_t delay);
static bool timerActive;
static sem_t timerSem;
pthread_t timerThread;
pthread_attr_t attrs;
struct sched_param priParam;
static void *msp432e4_timer(void *argUnused) {
sem_wait(&timerSem);
timerActive = true;
sem_post(&timerSem);
TaskSleep(40);
sem_wait(&timerSem);
timerActive = false;
sem_post(&timerSem);
return (NULL);
}
void initTimer() {
int retc;
pthread_attr_init(&attrs);
priParam.sched_priority = 1;
retc = pthread_attr_setschedparam(&attrs, &priParam);
retc |= pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
retc |= pthread_attr_setstacksize(&attrs, 1024);
if (retc != 0) {
// failed to set attributes
while (1) {}
}
timerActive = false;
if((sem_init(&timerSem, 0, 0)) != 0) {
while(1);
}
sem_post(&timerSem);
}
/*
* return true on starting a new timer
* false implies timer already active
*/
void timerStart() {
int retc;
retc = pthread_create(&timerThread, &attrs, msp432e4_timer, NULL);
if (retc != 0) {
// pthread_create() failed
while (1) {}
}
}
/* return true if timer active */
bool timerCheck() {
bool retval;
sem_wait(&timerSem);
retval = timerActive;
sem_post(&timerSem);
return(retval);
}
The TaskSleep function is a call to a freeRTOS TaskDelay function. It's used in many points throughout the system and has never been an issue.
Hopefully someone can point me in the right direction.
But you didn't really post enough of your code to determine where the problems might be, but I thought this might be worth mentioning:
A general problem is that the sample code you have is open loop wrt thread creation; that is there is nothing to throttle it, and if your implementation has a particularly slow thread exit handling, you could have many zombie threads lying around that haven't died yet.
In typical embedded / real time systems, you want to move resource allocation out of the main loop, since it is often non deterministic. So, more often you would create a timer thread, and park it until it is needed:
void *TimerThread(void *arg) {
while (sem_wait(&request) == 0) {
msp432e4_timer(void *arg);
}
return 0
}
void TimerStart(void) {
sem_post(&request);
}

How to check if a function is calling back to itself

Let's say we have a C function funA in a library, inside funA it'll call some other functions funB, funC, .etc. It's possible that funB and funC could call funA back. So the question is:
Is it possible to detect this situation just inside funA, something like:
void funA(void) {
if (...) {
// Calling back to funA
}
}
Conclusion
In a single thread environment, static/global variable would work.
In multi-thread environment, would have to depend on TLS support.
Haven't got any answer that can achieve this with just language(C) level tricks
This can be done with a static flag.
When the function is called, if the flag is not set then set it and continue, otherwise return right away. Then at the end of the function, you clear the flag so you can enter it again.
void funcA(void)
{
static int callback = 0;
if (callback) return;
callback = 1;
...
callback = 0;
}
If this needs to work in multiple thread separately you can declare the variable as _Thread_local instead of static.
If it is a single call only, you can have a global/static flag set once this function is called, and check it in the beginning. Or to remove the restriction of being single call, you can reset this flag before the function is returning.
Something like that:
void funA(void) {
static bool used = false;
if (used)
{
printf("It is used!\n");
}
used = true;
// .... Do stuff here, including possible recursion
used = false;
}
Note - this won't work with multithreading - this function is not reentrant..
maybe another approach you can identify the caller:
void func_a(void *ptr);
void func_b(void);
void func_c(void);
void func_a(void *caller)
{
if(caller == func_a)
{
printf("called from func_a\n");
return;
}
if(caller == func_b)
{
printf("called from func_b\n");
return;
}
if(caller == func_c)
{
printf("called from func_c\n");
return;
}
if(caller == NULL)
{
printf("called from somewhere elese - going to call myself\n");
func_a(func_a);
}
}
void func_b()
{
func_a(func_b);
}
void func_c()
{
func_a(func_c);
}
int main()
{
func_b();
func_c();
func_a(NULL);
return 0;
}
With a level of indirection, you can even count the number of times your function has been called:
void func( int count )
{
printf( "Count is %d\n", count );
if ( ... ) // no longer want to recurse...
{
return;
}
func( count + 1 );
}
// wrap the actual recursive call to hide the parameter
void funA()
{
func( 0 );
}
This way, it's fully thread-safe. If you don't want a wrapper function nor a parameter passed, you can use thread-specific storage.

map function pointers to specific numbers at runtime

I have a problem that i can even start to work on because i don't get it how can be done.
So we have a code
int test_handler() {
printf("Test handler called\n");
return 1;
}
// Test your implementation here
int main()
{
register_irq_handler(30, &test_handler);
do_interrupt(29); // no handler registered at this position, should return zero
do_interrupt(30); // calls handler at position 30, expected output: Test handler called
return 0;
}
I need to make those functions register_irq_handler, do_interrupt(29).
But i have no clue how to start, i am looking for a little help to send me on the right direction.
How i store 30 to point to this function when we don't have a global variable to store that "connection" or i am missing something.
You can't do it without a global variable (why would having a global variable be a problem?).
You probably need something like this:
// array of 30 function pointers (all automatically initialized to NULL upon startup)
static int(*functionpointers[30])();
void register_irq_handler(int no, int(*fp)())
{
functionpointers[no] = fp;
}
int do_interrupt(int no)
{
if (functionpointers[no] != NULL)
{
// is registered (!= NULL) call it
return (*functionpointer[no])();
}
else
{
// not registered, just return 0
return 0;
}
}
Disclaimer
This is non tested non error checking code just to give you an idea.

Mutex for getter method causes deadlock

Hi, I wanted to ask what is the best solution for the following problem. (explained below)
I have following memory library code (simplified):
// struct is opaque to callee
struct memory {
void *ptr;
size_t size;
pthread_mutex_t mutex;
};
size_t memory_size(memory *self)
{
if (self == NULL) {
return 0;
}
{
size_t size = 0;
if (pthread_mutex_lock(self->mutex) == 0) {
size = self->size;
(void)pthread_mutex_unlock(self->mutex);
}
return size;
}
}
void *memory_beginAccess(memory *self)
{
if (self == NULL) {
return NULL;
}
if (pthread_mutex_lock(self->mutex) == 0) {
return self->ptr;
}
return NULL;
}
void memory_endAccess(memory *self)
{
if (self == NULL) {
return;
}
(void)pthread_mutex_unlock(self->mutex);
}
The problem:
// ....
memory *target = memory_alloc(100);
// ....
{
void *ptr = memory_beginAccess(target);
// ^- implicit lock of internal mutex
operationThatNeedsSize(ptr, memory_size(target));
// ^- implicit lock of internal mutex causes a deadlock (with fastmutexes)
memory_endAccess(target);
// ^- implicit unlock of internal mutex (never reached)
}
So, I thought of three possible solutions:
1.) Use a recursive mutex. (but I heard this is bad practice and should be avoided whenever possible).
2.) Use different function names or a flag parameter:
memory_sizeLocked()
memory_size()
memory_size(TRUE) memory_size(FALSE)
3.) Catch if pthread_mutex_t returns EDEADLK and increment a deadlock counter (and decrement on unlock) (Same as recursive mutex?)
So is there another solution for this problem? Or is one of the three solutions above "good enough" ?
Thanks for any help in advance
Use two versions of the same function, one that locks and the other that doesn't. This way you will have to modify the least amount of code. It is also logically correct since, you must know when you are in a critical part of the code or not.

switching up/down the stack with getcontext/setcontext

I am trying to understand if getcontext/setcontext will work correctly in a specific scenario.
I can see how setcontext() can be used to unwind the stack back to a certain place in history.
#include <stdio.h>
#include <ucontext.h>
int rollback = 0;
ucontext_t context;
void func(void)
{
setcontext(cp);
}
int main(void)
{
getcontext(&context);
if (rollback == 0)
{
printf("getcontext has been called\n");
rollback++;
func();
}
else
{
printf("setcontext has been called\n");
}
}
But I was wondering if after an unwind you can re-wind back to a place that was in the future? I suppose this depends on the getcontext() call captures a copy of the stack and I can't find the exact details in the documentation.
#include <stdio.h>
#include <ucontext.h>
int rollback = 0;
int backToFuture = 0;
ucontext_t context;
ucontext_t futureContext;
void func(void)
{
// Some complex calc
if (some-condition)
{
getcontext(&futureContext); // After returning I want to come back
// here to carry on with my work.
if (backToFuture == 0)
{
setcontext(&context); // rewind to get stuff-done
}
}
// Finishe work
}
int main(void)
{
getcontext(&context);
if (rollback == 0)
{
printf("getcontext has been called\n");
rollback++;
func();
// eventually always return here.
}
else
{
printf("setcontext has been called\n");
// Do specialized work that needed to be done
// May involve function calls.
//
// I worry that anything the adds new stack frames
// will disrupt the saved state of futureContext
//
// But without detailed information I can not be sure
// if this is an allowed senario.
backToFuture = 1;
setcontext(&futureContext);
}
}
getcontext doesn't copy stack, it only dumps registers (including stack pointer) and a little context data like signal mask, etc.
When you jump down the stack it invalidates the top context. Even if you won't do any function calls think about the signal handler that can execute there. If you want to jump between two stacks you need to makecontext.
I added variable that demonstrates that your code is invalid:
void func(void)
{
// Some complex calc
if (1)
{
volatile int neverChange = 1;
getcontext(&futureContext); // After returning I want to come back
// here to carry on with my work.
printf("neverchange = %d\n", neverChange);
if (backToFuture == 0)
{
setcontext(&context); // rewind to get stuff-done
}
}
// Finishe work
}
On my machine it results in:
getcontext has been called
neverchange = 1
setcontext has been called
neverchange = 32767

Resources