So I have seen that many suggestions on implementing a state machine in C involve a state struct or the like, but I was wondering why we can't just use a while(1) for very simple state machines. For example,
int currentstate = state1;
void state1function(){
dosomething();
if(user chooses to go to state 2){
currentstate = state2;
}
}
int main{
while(1){
if(currentstate == state1){
state1function();
}
else if (currenstate == state2){
state2function();
}
Basically keeping track of the state in a global variable, and in the while loop calling a function depending on the state. This seems simple to me and i don't really see why it wouldn't work.
Can anyone please tell me why something like this would not work/would not be recommended?
Thanks
Sooner or later, using this approach, you will find that it would be convenient to have:
An explicit transition table.
OnEntry(), OnExit(), Do(), OnEvent() functions for each state.
Actions performed on a transition.
Guards. (explicit conditions for transitions to be triggered)
Nested state machines.
Concurrent state machines. Meaning: Multiple FSM running next to each other.
Communicating concurrent, nested state machines.
Somewhere along this ladder of sophistication, you will most likely abandon the brute force style, you started with, which might have looked like the code you gave in your question.
The while(1) construct is quite unrelated to state machines. It is used whenever a single thread of execution (main() or OS threads) are long-running, as they typically are on embedded systems or server-applications. If the application is written in form of a state machine or in other forms, does not really matter.
Depending on the problem you're trying to solve, a global or a static is a straightforward solution. Using a struct comes in handy when you need to manage more than one state machine at a time, and/or when you need to change state from more than one thread or process.
The while loop without wait will consume lot of CPU. I think an event mechanism using mutex or seamphores will be useful.
C is not asynchronous (by default). An infinite loop will just cause your program to "freeze" until the results are done.
Related
I have seen quite a lot of code that uses the cycle time of the Runnable for implementing some timer/timeout. The problem is that if someone decides to change the cycle time of this Runnable, the timer will be incorrect.
Example:
#define FOO_TIMER_100MS_REACHED (10U)
FUNC(void, FOO_CODE) FOO_Cycle_10ms( void )
{
static uint8 t = 0;
if( t < FOO_TIMER_100MS_REACHED )
{
t++;
}
else
{
; /* 100ms elapsed - do whatever is necessary */
}
}
So, how can I determine the cycle time of periodically triggered function FOO_Cycle_10ms from inside this Runnable?
In respect to the example above I'm looking for something like:
#define FOO_TIMER_100MS_REACHED ((uint8)(100U / CYCLE_TIME_FOO_Cycle_10ms))
The problem is that if someone decides to change the cycle time of this Runnable, the timer will be incorrect.
But can that actually happen? The software component description (SWCD) is always strongly coupled with the implementation. If somebody would change e.g. the runnable name in the SWCD or remove an access point, the code wouldn't compile too.
Other parameters like the runnable to task mapping can be changed by the integrator in a later development stage, but the period is part of the SWCD and thus also coupled with the implementation.
So, IMHO the described issue should not occour. If this does't answer your question, please provide more information about the actual use case.
Well, the SWCD is actually your contract, that should be discussed on changes with the responsible of the SWCD and the developer. If not, then your process is flawed.
On the other side, there are some ways:
Maybe you can create an Constant value from your SWCD Timing Event period
Create a ClientServer Interface to the TimeService (Tm) Module and let it setup. The Tm allows some handy SW timers backed by some GPT Predef Timers
Create a ClientServer interface with StbM-ServiceNeeds to your SWCD.
Then you should be able to access the Synchronized Time Base.
I had the same discussion ones, because this actually happened for a hot-fix.
We saw a potential solution in feeding Os_Service, see SWS_Os_00560, into the components measuring time, but never really tried it.
The Stbm solution we saw also, because we did not have the module in the respective project.
I have two loops:
One loop gets data from a device and processes it. Scales received variables, calculates extra data.
Second loop visualizes the data and stores it.
There are lots of different variables that need to passed between those two loops - about 50 variables. I need the second loop to have access only to the newest values of the data. It needs to be able to read those variables any time they are needed to be visualized.
What is the best way to share such vector between two loops?
There are various ways of sharing data.
The fastest and simplest is a local variable, however that is rather uncontrolled, and you need to make sure to write them at one place (plus you need an indicator).
One of the most advanced options is creating a class for your data, and use an instance (if you create a by-ref class, otherwise it won't matter), and create a public 'GET' method.
In between you have sevaral other options:
queues
semaphores
property nodes
global variables
shared variables
notifiers
events
TCP-IP
In short there is no best way, it all depends on your skills and application.
As long as you're considering loops within the SAME application, there ARE good and bad ideas, though:
queues (OK, has most features)
notifiers (OK)
events (OK)
FGVs (OK, but keep an eye on massively parallel access hindering exec)
semaphores (that's not data comms)
property nodes (very inefficient, prone to race cond.)
global variables (prone to race cond.)
shared variables (badly implemented by NI, prone to race cond.)
TCP-IP (slow, awkward, affected by firewall config)
The quick and dirty way to do this is to write each value to an indicator in the producer loop - these indicators can be hidden offscreen, or in a page of a tab control, if you don't want to see them - and read a local variable of each one in the consumer loop. However if you have 50 different values it may become hard to maintain this code if you need to change or extend it.
As Ton says there are many different options but my suggestion would be:
Create a cluster control, with named elements, containing all your data
Save this cluster as a typedef
Create a notifier using this cluster as the data type
Bundle the data into the cluster (by name) and write this to the notifier in the producer loop
Read the cluster from the notifier in the consumer loop, unbundle it by name and do what you want with each element.
Using a cluster means you can easily pass it to different subVIs to process different elements if you like, and saving as a typedef means you can add, rename or alter the elements and your code will update to match. In your consumer loop you can use the timeout setting of the notifier read to control the loop timing, if you want. You can also use the notifier to tell the loops when to exit, by force-destroying it and trapping the error.
Two ways:
Use a display loop with SEQ (Single Element Queue)
Use a event structure with User Event. (Do not put two event structures in same loop!! Use another)
Use an enum with case structure and variant to cast the data to expected type.
(Notifier isn't reliable to stream data, because is a lossy scheme. Leave this only to trigger small actions)
If all of your variables can be bundled together in a single cluster to send at once, then you should use a single element queue. If your requirements change later such that the transmission cannot be lossy, then it's a matter of changing the input to the Obtain Queue VI (with a notifier you'd have to swap out all of the VIs). Setting up individual indicators and local variables would be pretty darn tedious. Also, not good style.
If the loops are inside of the same VI then:
The simplest solution would be local variables.
Little bit better to use shared variables.
Better is to use functional global variables (FGVs)
The best solution would be using SEQ (Single Element Queue).
Anyway for better understanding please go trough this paper.
I'm aiming to use a threadpool with pthreads and am trying to choose between these two models of threading and it seems to me that the peer model is more suitable when working with fixed input, whereas the boss/worker model is better for dynamically changing work items. However, I'm a little unsure of how exactly to get the peer model to work with a threadpool.
I have a number of tasks that all need to be performed on the same data set. Here's some simple psuedocode for how I would look at tackling this:
data = [0 ... 999]
data_index = 0
data_size = 1000
tasks = [0 ... 99]
task_index = 0
threads = [0 ... 31]
thread_function()
{
while (true)
{
index = data_index++ (using atomics)
if index > data_size
{
sync
if thread_index == 0
{
data_index = 0
task_index++
sync
}
else
{
sync
}
continue
}
tasks[task_index](data[index])
}
}
(Firstly, it seems like there should be a way of making this use just one synchronisation point, but I'm not sure whether that's possible?)
The above code seems like it will work well for the case where the the tasks are known in advance, though I guess a threadpool is unnecessary for this particular problem. However even if the data items are still predefined across all tasks, if the tasks are not known in advance, it seems like the boss/worker model is better suited? Is it possible to use the boss/worker model but still allow the tasks to be picked up by the threads themselves (as above), where the boss essentially suspends itself until all tasks are complete? (Maybe this is still termed the peer model?)
Final question is regarding the synchronisation, barrier or condition variable and why?
If anyone can make any suggestions as to how better to approach this problem or even to poke holes in any of my assumptions, that would be great? Unfortunately I'm restricted from using a more higher-level library such as tbb for tackling this.
Edit: I should point out in case this isn't clear, each task needs to be completed in it's entirety before moving onto the next.
I'm a bit confused by your description here, hope the below is relevant.
I always looked at this pattern and found it very useful: The "boss" is responsible for detecting work and dispatching it to a worker pool based on some algorithm, from that time on, the worker is independent.
In this scenario, the worker is always waiting for work, not aware of any other instance, process requests and when it finishes, may trigger a notification of completion.
This has the advantage of good separation between the work itself and the algorithm that balance between the threads.
The other option is for the "boss" to maintain a pool of work items, and the workers to always pick them up as soon as they are free. But I guess this is more complex to implement and requires a larger amount of synchronization. I do not see the benefit of this second approach over the previous one.
Control logic and worker state is maintained by the "boss" in both scenarios.
As the paralleled work is done on a task, the "boss" "object" is handling a task, in a simple implementation, this "boss" blocks until a task is finished, allowing to call the next "boss" in line.
Regarding the Sync, unless I'm missing here something, you only need to sync once for all the workers to finish and this sync is done at the "boss" where the workers just send notifications that they finished.
This question may sound cliched, but I am in a situation here.
I am trying to implement a finite state automaton to parse a certain string in C. As I started writing the code, I realised the code may be more readable if I used labels to mark the different states and use goto to jump from one state to another as the case comes.
Using the standard breaks and flag variables is quite cumbersome in this case and hard to keep track of the state.
What approach is better? More than anything else I am worried it may leave a bad impression on my boss, as I am on an internship.
There is nothing inherently wrong with goto. The reason they are often considered "taboo" is because of the way that some programmers (often coming from the assembly world) use them to create "spaghetti" code that is nearly impossible to understand. If you can use goto statements while keeping your code clean, readable, and bug-free, then more power to you.
Using goto statements and a section of code for each state is definitely one way of writing a state machine. The other method is to create a variable that will hold the current state and to use a switch statement (or similar) to select which code block to execute based on the value of the state variable. See Aidan Cully's answer for a good template using this second method.
In reality, the two methods are very similar. If you write a state machine using the state variable method and compile it, the generated assembly may very well resemble code written using the goto method (depending on your compiler's level of optimization). The goto method can be seen as optimizing out the extra variable and loop from the state variable method. Which method you use is a matter of personal choice, and as long as you are producing working, readable code I would hope that your boss wouldn't think any different of you for using one method over the other.
If you are adding this code to an existing code base which already contains state machines, I would recommend that you follow whichever convention is already in use.
Using a goto for implementing a state machine often makes good sense. If you're really concerned about using a goto, a reasonable alternative is often to have a state variable that you modify, and a switch statement based on that:
typedef enum {s0,s1,s2,s3,s4,...,sn,sexit} state;
state nextstate;
int done = 0;
nextstate = s0; /* set up to start with the first state */
while(!done)
switch(nextstate)
{
case s0:
nextstate = do_state_0();
break;
case s1:
nextstate = do_state_1();
break;
case s2:
nextstate = do_state_2();
break;
case s3:
.
.
.
.
case sn:
nextstate = do_state_n();
break;
case sexit:
done = TRUE;
break;
default:
/* some sort of unknown state */
break;
}
I'd use a FSM generator, like Ragel, if I wanted to leave a good impression on my boss.
The main benefit of this approach is that you are able to describe your state machine at a higher level of abstraction and don't need to concern yourself of whether to use goto or a switch. Not to mention in the particular case of Ragel that you can automatically get pretty diagrams of your FSM, insert actions at any point, automatically minimize the amount of states and various other benefits. Did I mention that the generated FSMs are also very fast?
The drawbacks are that they're harder to debug (automatic visualization helps a lot here) and that you need to learn a new tool (which is probably not worth it if you have a simple machine and you are not likely to write machines frequently.)
I would use a variable that tracks what state you are in and a switch to handle them:
fsm_ctx_t ctx = ...;
state_t state = INITIAL_STATE;
while (state != DONE)
{
switch (state)
{
case INITIAL_STATE:
case SOME_STATE:
state = handle_some_state(ctx)
break;
case OTHER_STATE:
state = handle_other_state(ctx);
break;
}
}
Goto isn't neccessary evil, and I have to strongly disagree with Denis, yes goto might be a bad idea in most cases, but there are uses. The biggest fear with goto is so called "spagetti-code", untraceable code paths. If you can avoid that and if it will always be clear how the code behaves and you don't jump out of the function with a goto, there is nothing against goto. Just use it with caution and if you are tempted to use it, really evaluate the situation and find a better solution. If you unable to do this, goto can be used.
Avoid goto unless the complexity added (to avoid) is more confusing.
In practical engineering problems, there's room for goto used very sparingly. Academics and non-engineers wring their fingers needlessly over using goto. That said, if you paint yourself into an implementation corner where a lot of goto is the only way out, rethink the solution.
A correctly working solution is usually the primary objective. Making it correct and maintainable (by minimizing complexity) has many life cycle benefits. Make it work first, and then clean it up gradually, preferably by simplifying and removing ugliness.
I don't know your specific code, but is there a reason something like this:
typedef enum {
STATE1, STATE2, STATE3
} myState_e;
void myFsm(void)
{
myState_e State = STATE1;
while(1)
{
switch(State)
{
case STATE1:
State = STATE2;
break;
case STATE2:
State = STATE3;
break;
case STATE3:
State = STATE1;
break;
}
}
}
wouldn't work for you? It doesn't use goto, and is relatively easy to follow.
Edit: All those State = fragments violate DRY, so I might instead do something like:
typedef int (*myStateFn_t)(int OldState);
int myStateFn_Reset(int OldState, void *ObjP);
int myStateFn_Start(int OldState, void *ObjP);
int myStateFn_Process(int OldState, void *ObjP);
myStateFn_t myStateFns[] = {
#define MY_STATE_RESET 0
myStateFn_Reset,
#define MY_STATE_START 1
myStateFn_Start,
#define MY_STATE_PROCESS 2
myStateFn_Process
}
int myStateFn_Reset(int OldState, void *ObjP)
{
return shouldStart(ObjP) ? MY_STATE_START : MY_STATE_RESET;
}
int myStateFn_Start(int OldState, void *ObjP)
{
resetState(ObjP);
return MY_STATE_PROCESS;
}
int myStateFn_Process(int OldState, void *ObjP)
{
return (process(ObjP) == DONE) ? MY_STATE_RESET : MY_STATE_PROCESS;
}
int stateValid(int StateFnSize, int State)
{
return (State >= 0 && State < StateFnSize);
}
int stateFnRunOne(myStateFn_t StateFns, int StateFnSize, int State, void *ObjP)
{
return StateFns[OldState])(State, ObjP);
}
void stateFnRun(myStateFn_t StateFns, int StateFnSize, int CurState, void *ObjP)
{
int NextState;
while(stateValid(CurState))
{
NextState = stateFnRunOne(StateFns, StateFnSize, CurState, ObjP);
if(! stateValid(NextState))
LOG_THIS(CurState, NextState);
CurState = NextState;
}
}
which is, of course, much longer than the first attempt (funny thing about DRY). But it's also more robust - failure to return the state from one of the state functions will result in a compiler warning, rather than silently ignore a missing State = in the earlier code.
I would recommend you the "Dragon book": Compilers, Principles-Techniques-Tools from Aho, Sethi and Ullman. (It is rather expensive to buy but you for sure will find it in a library). There you will find anything you will need to parse strings and build finite automatons. There is no place I could find with a goto. Usually the states are a data table and transitions are functions like accept_space()
I can't see much of a difference between goto and switch. I might prefer switch/while because it gives you a place guaranteed to execute after the switch (where you could throw in logging and reason about your program). With GOTO you just keep jumping from label to label, so to throw in logging you'd have to put it at every label.
But aside from that there shouldn't be much difference. Either way, if you didn't break it up into functions and not every state uses/initializes all local variables you may end up with a mess of almost spaghetti code not knowing which states changed which variables and making it very difficult to debug/reason about.
As an aside, can you maybe parse the string using a regular expression? Most programming languages have libraries that allow using them. The regular expressions often create an FSM as part of their implementation. Generally regular expressions work for non arbitrarily nested items and for everything else there is a parser generator(ANTLR/YACC/LEX). It is generally much easier to maintain a grammar/regex than the underlying state machine. Also you said you were on an internship, and generally they might give you easier work than say a senior developer, so there is a strong chance that a regex may work on the string. Also regular expressions generally aren't emphasized in college so try using Google to read up on them.
What is the best way to write a state machine in C?
I usually write a big switch-case statement in a for(;;), with callbacks to re-enter the state machine when an external operation is finished.
Do you know a more efficient way?
I like the Quantum Leaps approach.
The current state is a pointer to a function that takes an event object as argument. When an event happens, just call the state function with that event; The function can then do its work and transition to another state by just setting the state to another function.
E.g.:
// State type and variable, notice that it's a function pointer.
typedef void (*State)(int);
State state;
// A couple of state functions.
void state_xyz(int event) { /*...*/ }
void state_init(int event) {
if (event == E_GO_TO_xyz) {
// State transition done simply by changing the state to another function.
state = state_xyz;
}
}
// main contains the event loop here:
int main() {
int e;
// Initial state.
state = state_init;
// Receive event, dispatch it, repeat... No 'switch'!
while ((e = wait_for_event()) != E_END) {
state(e);
}
return 0;
}
The QL frameworks provides helpers for extra things like entry/exit/init actions, hierarchical state machines, etc. I highly recommend the book for a deeper explanation and good implementation of this.
The best way is largely subjective, but a common way is to use a "table-based" approach where you map state codes (enums or some other integral type) to function pointers. The function returns your next state and other associated data and you loop through this until the terminal state is reached. This might in fact be what you are describing as your approach above.
That's pretty much the standard approach. If you're interested in studying a well considered library and comparing specifics, take a look at Ragel:
Ragel compiles executable finite state machines from regular languages. Ragel targets C, C++, Objective-C, D, Java and Ruby. Ragel state machines can not only recognize byte sequences as regular expression machines do, but can also execute code at arbitrary points in the recognition of a regular language. Code embedding is done using inline operators that do not disrupt the regular language syntax.
Switch statements are a good way to get started, but they tend to get unwieldy when the FSM gets larger.
A couple related (or duplicate) SO questions with great information and ideas:
state machines tutorials
C state-machine design
I used this pattern. Is there a typical state machine implementation pattern? (check best answer).
But i also add some features
1. Information about previous state.
2. Parameter passing
3. Adding external events like global timeout and "resseting SM"
I found state machines little less cryptic and maintainable.
Anyway, I still think state machines are most difficult and annoying programming task.(I got so far)
An alternative approach is a 2D array that describes for each state/event combination the actions to execute and the next state to go to. This can get trickier to manage when you need to transition to different states depending on 'circumstances', but it can be made to work well. You have an event recognizer function which returns the next event; you have the table where each entry in the table identifies the function to call on receiving the event and the next state to go to - unless the called function overrides that state.
Actually generating such code is fiddlier - it depends on how the FSM is described in the first place. Spotting duplicate actions is often important. Often, you can rely on 'sparse matrix' techniques that do not record error handling explicitly: if the entry logically exists in the sparse matrix, you act on that event/state information, but if the entry does not exist you fall back onto appropriate error reporting and resynchronization code.
A 2D array of pointers to structures can be passed into a generic FSM function; the fact that you write a triple-pointer is enough to make you cautious about what is going on. (I wrote one of those back in March 1986 - I don't have the source for that on disk any more, though I do still have a printout of the document that described it.)
Have a look here: http://code.google.com/p/fwprofile/
It's an open source version (GNU GPLv3) of the state machine implemented
in C. The concept and implementation is well-suited for use in
mission-critical applications. There are deployments in industrial
applications.
I use function pointers and a 2d look-up table where I use the state for one parameter and the event as the other.
I use excel (or any spreadsheet tool) to map a function to every state/event combination.
When an event occurs, I que it up, so then I have something that looks like this
int main(void)
{
StateList currentState = start_up;
EventList currentEvent;
uint8_t stateArray[STATE_COUNT][EVENT_COUNT];
InitializeStateArray(stateArray);
InitializeEventQue();
while(1)
{
currentEvent = GetPriorityEvent();
currentState = (StateList)(*(stateArray[currentState][currentEvent]))();
}
return 1; //should never get here
}
This method essentially forces the developer to consider all possible events in each state, and in my experience makes debugging a little easier.
You can use minimalist uml-state-machine framework implemented in c. It supports both finite and hierarchical state machine. The framework is very minimalist. It has only 3 API's, 2 structures and 1 enumeration.
The State machine is represented by state_machine_t structure. It is an abstract structure that can be inherited to create a state machine.
//! Abstract state machine structure
struct state_machine_t
{
uint32_t Event; //!< Pending Event for state machine
const state_t* State; //!< State of state machine.
};
State is represented by pointer to state_t structure in the framework.
If framework is configured for finite state machine then state_t contains,
typedef struct finite_state_t state_t;
// finite state structure
typedef struct finite_state_t{
state_handler Handler; //!< State handler function (function pointer)
state_handler Entry; //!< Entry action for state (function pointer)
state_handler Exit; //!< Exit action for state (function pointer)
}finite_state_t;
If framework is configured to support hierarchical state machine. It contains additional three members to represent the hierarchical relation between the states.
typedef struct hierarchical_state_t state_t;
//! Hierarchical state structure
typedef struct hierarchical_state_t
{
state_handler Handler; //!< State handler function
state_handler Entry; //!< Entry action for state
state_handler Exit; //!< Exit action for state.
const state_t* const Parent; //!< Parent state of the current state.
const state_t* const Node; //!< Child states of the current state.
uint32_t Level; //!< Hierarchy level from the top state.
}hierarchical_state_t;
The framework provides an API dispatch_event to dispatch the event to the state machine and two API's for the state traversal.
state_machine_result_t dispatch_event(state_machine_t* const pState_Machine[], uint32_t quantity);
state_machine_result_t switch_state(state_machine_t* const pState_Machine, const state_t* pTarget_State);
state_machine_result_t traverse_state(state_machine_t* const pState_Machine, const state_t* pTarget_State);
For more details refer to GitHub project.
check this out "https://github.com/knor12/NKFSMCompiler" it helps generate C Language code for a state machine defined in an scxml or csv file. an example is provided.