Returning program to pre-triggered state - c

First this gets triggered:
if ((temperatureChannel[channelID].currentTemperature > temperatureChannel[channelID].highLimit) | (temperatureChannel[channelID].currentTemperature < temperatureChannel[channelID].lowLimit))
activateAlarm(channelID);
Activate alarm is triggered, then from there:
void activateAlarm(int channelID);
{ while (temperatureChannel[channelID].currentTemperature > temperatureChannel[channelID].highLimit || temperatureChannel[channelID].currentTemperature < temperatureChannel[channelID].lowLimit)
{
logSubsystem(temperatureChannel[channelID].currentTemperature);
}
}
Then alarm screen is triggered with following case:
int logSubsystem(int currentTemperature)
case 'F': //if user input is 'F'
case 'f': //if user input is 'f'
currentTemperature--;
printf("your current exceeded temp is %i\n \n", currentTemperature);
if (currentTemperature <= 100 || currentTemperature >= 50);
compareLimit();
break; //exits loop
How do I set up this function so that if the user decrements with F and gets the current temperature to below the limit (<100, or >50), then it will return back to the compareLimit function and the requirement for the high limit/low limit triggered state will be FALSE, returning the program to its original pre-alarm state?

I think you would benefit considerably from thinking a lot about how your program flows. Right now, what I can deduce of your program flow is:
You have an outer loop that checks the temperature, on at least one channel ID. Inside that loop, you have the if statement you first showed us.
Then activate alarm does some other stuff, but loops until the temperature goes down, calling logSubsystem.
logSubsystem then presumably gets some kind of user input, and from there, you want it to call to your initial function, presumably called prepare limit.
The problem with this is that none of these functions ever complete. They all call each other, and you'll eventually get a stack overflow. Nice, since that's the name of this site, but not something you want to aspire to.
What you basically need is a state machine. You need something that keeps track of values, looks at those values, and calls functions that return that operate on those values. There should only be one loop, and it should do all the control of what happens based on what those values are. The good news is, you have all of this in place already. temperatureChannel is keeping track of the values for you, and you have while loops a-plenty.
Let me give you my suggestion of the way I suggest your program should flow:
bool checkTemperatureValuesOutOfRange(int channelID) {
// this is just a convenience, to make the state machine flow easier.
return (temperatureChannel[channelID].currentTemperature > temperatureChannel[channelID].highLimit) || // note the || not just one |
(temperatureChannel[channelID].currentTemperature < temperatureChannel[channelID].lowLimit);
}
void actOnUserInput() {
char input = // ... something that gets a user input. It should check if any is available, otherwise return.
switch (input) {
case 'F':
case 'f':
temperatureChannel[channelID].currentTemperature--;
break; // This doesn't exit the loop - it gets you out of the switch statement
}
void activateAlarm(int channelID) {
// presumably this does something other than call logSubsystem?
// if that's all it does, just call it directly
// note - no loop here
logSubsystem(channelID);
}
void logSubsystem(int channelID) { // Not the current temperature - that's a local value, and you want to set the observed value
// I really think actOnUserInput should be (an early) part of the while loop below.
// It's just another input for the state machine, but I'll leave it here per your design
// Presumably actually logs things, too, otherwise it's an unnecessary function
actOnUserInput();
}
while (TRUE) { // this is the main loop of your function, and shouldn't exit unless the program does
// do anything else you need to - check other stuff
// maybe have a for loop going through different channelIDs?
if (checkTemperatureValuesOutOfRange(channelID)) {
activateAlarm(channelId);
// do anything else you need to
}
I'm sure you can see lots of differences between your code and mine. Here are some key things to consider:
All the functions now return. The master while loop calls functions that check status, and calls function that change status.
I would highly suggest acting on the user input as part of the master while loop. It's just another input to the state machine. Get it, act on it, and then check your statuses. You presumably need to have some input from the user, otherwise you'll never get in a bad state in the first place.
Right now, activate alarm happens every time. With the code you showed, that's fine - because logSubsystem was all that was being called. If you only want the alarm to ring once, keep a boolean tracker inside temperatureChannel[channelId] that says if the alarm rang, set it true within activateAlarm, and then reset it to false based on the return value of checkTemperatureValuesOutOfRange.
Rather than leaving yourself in the activateAlarm/logSubsystem area, you return each time, and check your values each time to see if you're still there. This is the key point - your functions should be fast, and not monopolize your processor. Make each function do just one sort of thing, and have all the control come from within the master loop.
I made a lot of changes to your code, and I don't know if you're allowed to make all of them, but you'll need something similar to this. It's much more robust, and gives you room to grow all around.

Related

Understanding code sbuf_remove(sbuf_t *sp) from book CSAPP? : issue for location of P(&sp->items)

As reading the book < Computer Systems: A Programmer's Perspective > and in the chapter of Concurrent Programming, I saw a this function:
int sbuf_remove(sbuf_t *sp){
int item; '
P(&sp->items);
P(&sp->mutex);
if (++sp->front >= sp->n)
sp-> front = 0;
item = sp->buf[sp->front]
V(&sp->mutex);
V(&sp->slots);
return item;
}
After reading the code, I think some problematic situation.
Problematic Situation's conditions :
&sp->items = 1 ,
two consumers reach at P(&sp->items) code at same time (before none of them reach to P(&sp->mutex);
In this situation, I think two consumers should have race and make problem.
(After one consumer_1 finish sbuf_remove, items become 0 but consumer_2 already pass P(&sp->items) code. Therefore consumer_2 fail to get correct item and return unexpectable value.)
I am wondering why package developer did not use mutex's lock code before enter items, slots semasphore.
I mean the code should be changed like this. Isn't it more safe than original code?
P(&sp->mutex);
P(&sp->items);
if (++sp->front >= sp->n)
sp-> front = 0;
item = sp->buf[sp->front]
V(&sp->slots);
V(&sp->mutex);
Remember that sem_wait waits until the semaphore is nonzero before atomically decrementing it. So if two consumers reach P(&sp->items) at the same time with sp->items==1, one of them will decrement items and go on to remove the last item. The other will see that items == 0 and block until some producer adds an item. They cannot both pass P(&sp->items). I don't see any race here.
On the other hand your "more safe" suggestion is a little too safe. Suppose a consumer enters sbuf_remove when the queue is empty, so sp->items == 0. It takes the mutex and then blocks (still holding the mutex!) waiting for sp->items to become positive, which will only happen when a producer adds an item. But in order to add an item to the queue, the producer presumably would need to take the mutex, which it can't do because the consumer holds it. We thus have a classic deadlock.

threads in c, how to use them to move a player?

Update my code
So i am working on a 2d game in c, now i am using threads to do different stuff in the same time, to move the player, cars etc.
But somehow i don't get it how can i move my player just one step, i know that the problem lays in my global variable movement. But can figure it how to do it the right way. So i hope someone can help me.
The code is huge so i will not passt all of it but the parts that are interesting for the player movement.
void moveFroggy() {
// froggy.y = SCREEN_HEIGHT - OUTER_BORDER;
if((movement == 'a') && (froggy.x > OUTER_BORDER))
froggy.x--;
if((movement == 'd') && (froggy.x < (SCREEN_WIDTH - OUTER_BORDER)))
froggy.x++;
if ((movement == 'w') && (froggy.y >= (SCREEN_HEIGHT - NUM_LANES - OUTER_BORDER - GRASS_BORDER)))
froggy.y--;
if ((movement == 's') && (froggy.y < (SCREEN_HEIGHT - OUTER_BORDER)))
froggy.y++;
if(movement == 'q')
quit = 1;
if(froggy.y <= (SCREEN_HEIGHT - NUM_LANES - OUTER_BORDER - GRASS_BORDER))
player_won = 1;
movement = '0';
}
Now inside the main we have a while loop that runs all the time, till the player complete the game or quit it.
pthread_create(&input_t, NULL, input_runner, NULL);
while(!quit && !error && !player_lost && !player_won) {
moveFroggy();
moveCarsOnMotorway();
startCar((SCREEN_WIDTH - OUTER_BORDER));
drawScreen();
usleep(GAME_SPEED);
}
pthread_join(input_t, NULL);
So my input_t thread is calling the input_runner function inside that function i get the user input.
void *input_runner(void* arg) {
char input;
if(!player_lost || !player_won){
while((input = getchar()) != EOF){
movement = input;
}
}
pthread_exit(0);
}
Just to know movement is a global variable so i can use it for moveFroggy function. but that is the problem to because it stores "w" and it just repeat itself till the user hit any other command. But it should move the player just one step ahead, so how can i reset the value and how to do proper clean up for threads if one is needed.
I am new in using thread,
Well, it seems the simple way to only move one step would be, at the bottom of moveFroggy() to clear movement value.
As an aside, it looks like you're creating an input-processing thread on every iteration of your game loop; is that really what you intend? If you want an input-processing thread, why not have it run its own loop to constantly read input until the game is over?
I'm also not sure of this overall multithreading strategy, but perhaps it will work for you...
This is not a good use of threads, and will be prone to synchronization errors.
Variables that are accessed by multiple threads must be protected by a mutex or accessed using atomic methods. Failing to do so will result in unpredictable behavior.
In any case, you don't need threads for this. If you want to read from the keyboard without blocking, there are a number of ways of doing that, including:
If on Linux, use the ncurses library, which natively provides non-blocking keyboard input through getch().
If on Windows, use kbhit().
Use fcntl() with F_SETFL to set standard input as non-blocking.
Use select() or poll() to check for input before trying to read.
Avoid the console entirely, and use a graphics library such as SDL.

Call a function when counter reaches some value without if statement

Lets say I have a function named loop(). In this loop() I increment a counter count.
I have few functions, A(), B(), C(), etc.
I want to call each one of these functions when the counter reaches some value (different for every function).
My current code looks like:
static unsigned int count = 0;
void loop(){
if (count == VALUE_ONE)
A();
if (count == VALUE_TWO)
B();
if (count == VALUE_THREE)
C();
..... //more cases
if (count == MAX_VAL)
count = 0;
else
count++;
}
VALUE_* are #defines so they are not being changed during the program.
Right now I am using regular if statements to check the counter value. But I want to avoid using the if statement to avoid branch mispredictions.
Is there a better way to do this? Something that will actually avoid branch mispredictions etc?
Edit:
The goal here is to optimize this part of code in order to make it in faster, as for now it sometimes doesn't finish until the time it should. I am aware that there might be a problem with function A(), B(), etc, but for now I am asking about this specific case.
To make it clear, VALUE_ONE, VALUE_TWO, VALUE_THREE, etc might be very large values and not increasing by 1. For example it might be:
#define VALUE_ONE 20
#define VALUE_TWO 1500
#define VALUE_THREE 99777
My compiler version is: gcc (GCC) 4.4.7
Why in the world are you worried about branch misprediction? Do you have a working program? Does it run too slowly? Have you narrowed the problem to branch misprediction in the code you present? Unless the answer to each of those questions is "yes", you are engaging in premature optimization.
Moreover, the conditional branches in the code you present appear to be highly predictable, at least if the counter is expected routinely to reach values in the tens or hundreds of thousands or more, as the updated example code seems to indicate. A misprediction rate on the order of 0.00001 or less -- which is about what you could expect -- will not have a measurable performance impact. Indeed, handling code such as you've presented is the bread and butter of branch prediction. You could hardly ask for a case more friendly to a branch-prediction unit.
In any event, since you are concerned about branch misprediction, your question must be not so much about avoiding the if statements in particular, but about avoiding conditional logic in general. As such, a switch construct probably is not better, at least not for the situation you describe, wherein you want to call functions only for a handful of the large number of distinct values the function will see, sprinkled across a wide range. Although the compiler could, in principle, implement such a switch via a jump table, it is unlikely to do so in your case because of how large the needed table would be, and how few of the elements would differ from the one for the default case.
A hash table has also been discussed, but that's no better, because then either you need conditional logic to distinguish between cache hits and cache misses, or else your hash table must for every input provide a function (pointer) to be called. Calling a function on every iteration would be far more costly than what you are doing now.
Additionally, you need a perfect hash function to avoid conditional logic in the HT implementation. If the possible values of your counter are bounded by a small enough number that a hash table / perfect hash could be used to avoid conditional logic, then a plain array of function pointers would be lighter-weight than a hash table, and could serve the same purpose. It would still have the same problem with function-call overhead, however. If you insist on avoiding conditional logic then this would probably be the best way to go for your particular problem. But don't.
Leave optimisations to the compiler in the first place. Concentrate on writing human-readable code. Optimise only iff you have a timing problem and after you profiled the code. Then concentrate on the hot-spots. If some code is good for branch-prediction is hard to predict with modern CPUs.
Use a switch (for an easier to read introduction please check a good C book) statement to make the code better readable:
switch ( count ) {
case VALUE_ONE:
f1();
break;
case VALUE_TWO:
f2();
break;
...
default:
// be aware to catch illegal/forgotten values, unless you
// are absolutely sure they can be ignored safely.
// still having a default label is good style to signal "I
// though about it".
break;
}
That is not only the most readable version, but also gives the compiler the best chance to optimize the code.
If the values are just increasing by 1 (1, 2, 3, ...), modern compilers will automatically generate a jump-table, even for partial successions (1, 2, 3, 7, 8, etc.), so that is as fast as a manually created function-table. If they are not, it still often will generate something like if ... else if ... else if ... constructs.
Note the case-labels must be constant-expressions.
Edit: After you clarified the values may not be adcascent, my answer still holds true. Depending on the number of compare-values, the switch still is the best solution unless prooved wrong. Try this first, profile and only optimise iff necessary. A hash-table might not be worth the effort.
Even if you'd use a hash-function, the switch above will come in handy. Just use the hash-value instead of count.
I'm skeptical whether the original function is a bottleneck or an effective place to be optimizing. But hey, I like puzzles...
Given that the count is incrementing and the match values are increasing, you really only need to test against the upcoming match value. And while you can't use your match values as an array index you could create states that can be used as an array index. Try something like this.
static unsigned int count = 0;
typedef enum
{
WAITING_FOR_VALUE_ONE = 0,
WAITING_FOR_VALUE_TWO,
WAITING_FOR_VALUE_THREE,
...,
WAITING_FOR_MAX_VALUE,
MAX_STATES
} MyStates;
static MyStates state = WAITING_FOR_VALUE_ONE;
void waitForValueOne()
{
if (count == VALUE_ONE)
{
A();
state++;
}
}
void waitForValueTwo()
{
if (count == VALUE_TWO)
{
B();
state++;
}
}
void waitForMaxValue()
{
if (count == MAX_VAL)
{
count = 0;
state = 0;
}
}
void (*stateHandlers[MAX_STATES]) () =
{
waitForValueOne,
waitForValueTwo,
waitForValueThree,
...
waitForMaxValue
}
void loop()
{
(*stateHandlers[state])();
count++;
}
After count reaches MAX_VAL, your original implementation will run the next loop with count = 0 whereas my implementation will run the next loop with count = 1. But I'm sure you can fix that if it's important.
Update:
I don't like how loop called the state handler every count. It really only needs to call the state handler when there is a match. And also the comparison doesn't need to be repeated in every state handler function if it's performed in loop. Here are a few edits that implement this improvement.
static MyStates state = WAITING_FOR_VALUE_ONE;
static unsigned int matchValue = VALUE_ONE;
void waitForValueOne()
{
A();
state++;
matchValue = VALUE_TWO;
}
void waitForValueTwo()
{
B();
state++;
matchValue = VALUE_THREE;
}
void waitForMaxValue()
{
count = 0;
state = 0;
matchValue = VALUE_ONE;
}
void loop()
{
if (count == matchValue)
{
(*stateHandlers[state])();
}
count++;
}
In your case I can't see any reason for an optimiziation.
But in the case your interrupt will be fired every 20µs and your handler consumes 50% of the complete cpu time, as you check aginst 200 values, then and only then you could change your code.
For an incrementing counter, you only need a single if as you always know which value will be the next one.
void isr(void)
{
count++;
if (count == nextValue)
{
if ( count == VALUE_ONE )
{
A();
nextValue=VALUE_TWO;
}
else if ( count == VALUE_TWO )
{
B();
nextValue=VALUE_THREE;
}
...
}
}
In 99% of the time, the ISR() only needs to increment the counter and check that the value isn't reached.
In reallity, I would use an array of actions and times, instead of the if else if block.

ideal way to restart nested loops in C?

I am a newbie to microcontroller C programming and I am running into a few problems with using nested loops.
Following is a sample construct that I have in my C code. The problems are mentioned subsequently
// I am trying to ramp down the while loop
while (i>= stop_value)
{
step_value = default_value;
R32(a particular register, content_register);
if (content_register = a_set_value)
{
if( step_value <= step_max)
{
step_value = step_value +1;
i=start_value;
continue;
}
if(step_value =step_max)
{
// do something;
break;
}
}
WR32(a particular register, content_reset_register); // resetting the register
i=i-1;
}
Basically, I am trying to do the following:
ramp down a loop till it reaches the stop_value and also read a particular register while ramping down.
If the register has a defined value, then check if the step_value<= step_max. If step_value < step_max then reset the while loop by using continue statement, and setting i to initial start value. At this point of time, my step_value should be the latest value and not the default step value. I do understand that above code is not completely correct for step_value because I initialize step_value to default_value.( So, how do I modify the initial step_value = default_value statement so that first time when the loop executes, I have a default_value and subsequently the most recent step_value?)
But, if step_value equals my step_max then just do something and break subsequently( this part works!). Also, when I use the continue statement, I should reset the contents of the register.
So, I want to effectively reset the while loop with the latest step_value, contents of the register reset when my step_value is less than step_max? Thank you for your replies!
In this code:
if( step_value <= step_max)
{
step_value = step_value +1;
i=start_value;
continue;
}
if(step_value =step_max)
{
// do something;
break;
}
The second if cannot ever be reached. You are checking <= and then skipping to the bottom of the loop with continue.
From your above logic:
then check if the step_value<= step_max. If step_value < step_max then reset the while loop by using continue statement, and setting i to initial start value.
That code should probably read:
if( step_value < step_max)
{
step_value = step_value +1;
i=start_value;
continue;
}
...
Then the second if could be evaluated. This should be generating compiler warnings like crazy about unreachable code and assignment within if statements. Please turn on your compiler warnings and listen to them!
I assume that at least one of the following alternatives apply:
First, in C language = is an assigment which returns the value assigned and assumes true if that value is not equal to 0.
So you have to use == in all if statements instead of = (unless it is desired behaviour that you assign and check for != 0 in the if statement in one step - but even in that case I'd prefer to do this in 2 steps for better maintainability), i.e. instead of
if (content_register = a_set_value)
{
// your code
}
I would say
content_register = a_set_value;
if (content_register!=0)
{
// your code
}
to make it more clear what you're checking against.
Second, if step_value==step_max (and you're properly using == in the 2nd if) then both IFs are executed, which is not what you want. So you I assume you meant < instead of <=.
Third, from our chat I got the information from you that the loop is waiting for a register change coming from an external thread. In this case the loop is simply too fast resetting the register. Consider synchronization or at least add a thread sleep after resetting the register to allow the other thread to change the register.
Change this and see if it works.

Exit C function cleanly

I have a couple of functions. Basically a menu where a user can choose 1-n different options, and each of those options have a function associated with them. In this example it's been dumbed down.
What I am trying to determine is the best way to exit a function prematurely. For example, when the user presses enter whilst in the function of a menu option, I want the program to send them back to the menu without running anything else in that function.
In the case below, I simply call showMenu() and place a return statement after it. The only thing is, if the user quits multiple functions there will be a trail of return statements that needs to be unraveled at the end.
Could somebody please show me if there is a more efficient way to achieve this or whether I am on the money.
void showMenu()
{
//Display menu
//Prompt user for menu option
//Run function of appropriate menu option
runSelectedFunction();
}
void runSelectedFunction()
{
//Get user input for the function and validate
//Check if the user input was only a '\n' if so show the menu and exit
showMenu();
return;
//Do the stuff that this function is meant to do.
}
Looks good to me. Or - since there are many around that are against having multiple exit points form a single function - you could do:
void func()
{
//get input
if ( checkMenu() )
{
//do the stuff I am meant to do
}
else
{
showMenu();
}
}
so you are avoiding adding a second return to your function. Also you could have the showMenu() call always at the end of the function, depending on your needs
hth
Mario
The best way? In short, don't.
Why?
Although there's nothing technically wrong with it and you'll find it all over the place, it can sometimes lead to headaches when trying to track down bugs or memory leaks in complex code.
Use early returns only when absolutely necessary and even then try to find an alternative first :)
An alternative is to use the following pattern to ensure your function always returns from one place, giving you the opportunity to always free resources (or report errors, etc):
int func(void)
{
int ret = 0;
do
{
if (!allocate_resource())
{
ret = -1;
break;
}
if (!allocate_more_resources())
{
ret = -2;
break;
}
do_stuff();
}
while (0);
free_allocated_resources();
return (ret);
}

Resources