473,480 Members | 2,194 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

State Machine

Hi All,

I have with me two ways to implement a state machine.

One I use the switch statement:
switch ( media_event )
{
case EVENT_HIDE:
if ( media_state != STATE_HIDDEN )
media_state = STATE_HIDDEN;
function(a,b,c,d,e,f);
break;
Feb 5 '07 #1
6 2750
In article <11**********************@j27g2000cwj.googlegroups .com>,
holysmoke <su**********@gmail.comwrote:
>My question is:
1. What is the cost of calling dummy function above compared with cost
of two conditionals? Is question too platform specific? (FWIW I'm on
ARM9, using ADS)
Yes, the cost of any particular hardware operation as too variable
for us to get into here.
>2. Is introducing a conditional at the point of call the better
solution? (& of course replacing dummy with NULL in media_cb array
above)
if (media_cb[media_event][media_state] != NULL)
media_cb[media_event][media_state](x,y,z);
You'd have to measure to find out; and with the next compiler release
or with different compliation flags you might get a different result.
--
"It is important to remember that when it comes to law, computers
never make copies, only human beings make copies. Computers are given
commands, not permission. Only people can be given permission."
-- Brad Templeton
Feb 5 '07 #2
holysmoke wrote:
Hi All,

I have with me two ways to implement a state machine.

One I use the switch statement:
<snip>
>
Notice for every event there are two conditional statements.

Another way is use an array of function pointers:
static media_callback media_cb [EVENT_MAX][STATE_MAX] =
{
{dummy, media_hide, media_hide, media_hide },
...
};

media_cb[media_event][media_state](a,b,c,d,e,f);

My question is:
1. What is the cost of calling dummy function above compared with cost
of two conditionals? Is question too platform specific? (FWIW I'm on
ARM9, using ADS)
Can't say, you'd have to profile it, or at least look at the generated
assembly code.
2. Is introducing a conditional at the point of call the better
solution? (& of course replacing dummy with NULL in media_cb array
above)
if (media_cb[media_event][media_state] != NULL)
media_cb[media_event][media_state](x,y,z);
I'd probably go for something like

yourFunctionType fn = media_cb[media_event][media_state];

if( fn )
{
fn(x,y,z);
}

Unless profiling showed this to be too expensive and there was a faster
alternative.

--
Ian Collins.
Feb 5 '07 #3
Ian Collins wrote:
yourFunctionType fn = media_cb[media_event][media_state];

if( fn )
{
fn(x,y,z);
}

Unless profiling showed this to be too expensive and there was a faster
alternative.
OT: I've heard that modern compilers *can* also inline callbacks to code which
they have direct access to (i.e. not in another library, object file, etc.).
Feb 5 '07 #4
Christopher Layne <cl****@com.anodizedwrites:
OT: I've heard that modern compilers *can* also inline callbacks to code which
they have direct access to (i.e. not in another library, object file, etc.).
I've been testing this from time to time with GCC as it evolves,
because it has wonderful optimization potential, that would allow
some of the best of C++ templates to be implemented in C.

Imagine that you have a header file that defines an inline
qsort-like function named my_qsort(). Now, in a .c file, define
a comparison function for, say, ints, and write an extern
function that just calls my_qsort() passing that comparison
function. If all goes well, the sort and all the comparisons get
inlined by the compiler, so that you end up with a nice, fast
sort function with the modularity of callbacks but without the
performance penalty.

Now extend it by doing this with ADTs such as balanced binary
search trees and hash tables. With reasonable use of macros,
this is pretty spiffy.

But so far I haven't been able to get GCC to cooperate to the
extent that I want.
--
"You call this a *C* question? What the hell are you smoking?" --Kaz
Feb 5 '07 #5
Ben Pfaff wrote:
Imagine that you have a header file that defines an inline
qsort-like function named my_qsort(). Now, in a .c file, define
a comparison function for, say, ints, and write an extern
function that just calls my_qsort() passing that comparison
function. If all goes well, the sort and all the comparisons get
inlined by the compiler, so that you end up with a nice, fast
sort function with the modularity of callbacks but without the
performance penalty.

Now extend it by doing this with ADTs such as balanced binary
search trees and hash tables. With reasonable use of macros,
this is pretty spiffy.

But so far I haven't been able to get GCC to cooperate to the
extent that I want.
Yes. I seek that same holy grail that you also seek Ben. About the best I can
get out of it is this:

/* no error checking example */
#include <stdlib.h>
#include <stdio.h>

typedef struct cbt__ cbt;
typedef void (*cbt_cb_display)(cbt *);

struct cbt__ {
char *text;
cbt_cb_display display;
};

static void cbt_display(cbt *c)
{
fprintf(stdout, "c->text == %s\n", c->text);

return;
}

extern cbt *cbt_new(void)
{
cbt *c;

c = malloc(sizeof *c);
c->text = NULL;
c->display = cbt_display;

return c;
}

int main(int argc, char **argv)
{
cbt *c;

if (argc <= 1) return EXIT_FAILURE;

c = cbt_new();
c->text = argv[1];
c->display(c);

return 0;
}

Lots of x86 asm here:

No optimization on this one:
$ gcc -W -Wall -pedantic -O0 -S -o /dev/stdout cb.c
.file "cb.c"
.section .rodata
..LC0:
.string "c->text == %s\n"
.text
.type cbt_display, @function
cbt_display:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl 8(%ebp), %eax
movl (%eax), %eax
movl stdout, %edx
movl %eax, 8(%esp)
movl $.LC0, 4(%esp)
movl %edx, (%esp)
call fprintf
leave
ret
.size cbt_display, .-cbt_display
..globl cbt_new
.type cbt_new, @function
cbt_new:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl $8, (%esp)
call malloc
movl %eax, -4(%ebp)
movl -4(%ebp), %eax
movl $0, (%eax)
movl -4(%ebp), %eax
movl $cbt_display, 4(%eax)
movl -4(%ebp), %eax
leave
ret
.size cbt_new, .-cbt_new
..globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $36, %esp
movl %ecx, -28(%ebp)
movl -28(%ebp), %eax
cmpl $1, (%eax)
jg .L6
movl $1, -24(%ebp)
jmp .L8
..L6:
call cbt_new
movl %eax, -8(%ebp)
movl -28(%ebp), %edx
movl 4(%edx), %eax
addl $4, %eax
movl (%eax), %edx
movl -8(%ebp), %eax
movl %edx, (%eax)
movl -8(%ebp), %eax
movl 4(%eax), %edx
movl -8(%ebp), %eax
movl %eax, (%esp)
call *%edx # the callback from main().
movl $0, -24(%ebp)
..L8:
movl -24(%ebp), %eax
addl $36, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.ident "GCC: (GNU) 4.1.1"
.section .note.GNU-stack,"",@progbits
-----

Now we go hard core optimization:
$ gcc -W -Wall -pedantic -O3 -S -o /dev/stdout cb.c
.file "cb.c"
.text
.p2align 4,,15
..globl cbt_new
.type cbt_new, @function
cbt_new:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
movl $8, (%esp)
call malloc
movl $0, (%eax)
movl $cbt_display, 4(%eax)
leave
ret
.size cbt_new, .-cbt_new
.section .rodata.str1.1,"aMS",@progbits,1
..LC0:
.string "c->text == %s\n"
.text
.p2align 4,,15
.type cbt_display, @function
cbt_display:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl 8(%ebp), %eax
movl (%eax), %eax
movl %eax, 8(%esp)
movl $.LC0, %eax
movl %eax, 4(%esp)
movl stdout, %eax
movl %eax, (%esp)
call fprintf
leave
ret
.size cbt_display, .-cbt_display
.p2align 4,,15
..globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
movl $1, %eax
pushl %ebp
movl %esp, %ebp
subl $24, %esp
cmpl $1, (%ecx)
movl %ecx, -8(%ebp)
movl %ebx, -4(%ebp)
movl 4(%ecx), %ebx
jle .L8
movl $8, (%esp)
call malloc
movl $0, (%eax)
movl 4(%ebx), %edx
movl $cbt_display, 4(%eax)
movl %edx, (%eax)
movl %eax, (%esp)
call cbt_display # callback is not a deref here.
xorl %eax, %eax
..L8:
movl -8(%ebp), %ecx
movl -4(%ebp), %ebx
movl %ebp, %esp
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.ident "GCC: (GNU) 4.1.1"
.section .note.GNU-stack,"",@progbits
-----

So I guess that's about the best we can get unless there are some other
tricks. Calling "cbt_display(c)" results in a direct inline - which is what I
expected w/ "c->display(c)".
Feb 6 '07 #6
Ben Pfaff wrote:
Christopher Layne <cl****@com.anodizedwrites:

>>OT: I've heard that modern compilers *can* also inline callbacks to code which
they have direct access to (i.e. not in another library, object file, etc.).


I've been testing this from time to time with GCC as it evolves,
because it has wonderful optimization potential, that would allow
some of the best of C++ templates to be implemented in C.
That would be a good thing to have. Temples give the C++ standard
library algorithms the performance edge over their C counterparts.

--
Ian Collins.
Feb 6 '07 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
4302
by: Robert | last post by:
In Web.config file is a setting for sessionState. If I want to maintain a users' session state (ie use the Session object) in a web farm that is being load balanced by a Cisco CSS 11501 Switch. ...
0
800
by: Maciek | last post by:
Hi When I set Session state mode to StateServer (IIS 6.0; windows2003; .NET 2.0) in my application, I have recived this message:...
6
12512
by: nilavya | last post by:
HI, I have got a C++ application involving State machine. Now I have got too many states and too many events which changes the state of the Staet machine. So my code is somewhat unmanageable....
4
4364
by: Shawnk | last post by:
This post is intended to verify that true value semantics DO NOT EXIST for the Enum class (relative to boolean operations). If this is true then (thus and therefore) you can not design state...
4
7135
by: nyhetsgrupper | last post by:
I have a C++ application which I am porting to C#. This application is controlling a transport belt. This transport belt is moving bins foreward and backward. I have a state machine controlling...
67
7290
by: Rui Maciel | last post by:
I've been delving into finite state machines and at this time it seems that the best way to implement them is through an intense use of the goto statement. Yet, everyone plus their granmother is...
11
1878
by: tuom.larsen | last post by:
Dear list, I'm writing very simple state machine library, like this: _state = None def set_state(state): global _state _state = state
2
1668
by: tat | last post by:
Hi all, Sorry if this question is off-topic. I would like have your suggestion . I need to write one application which control a machine via serial port. There are 5 states in the following...
3
2395
by: Pallav singh | last post by:
Hi All i am getting Error while writing following code for state design Pattern kindly let me know How to Correct this Error ?? Thanks Pallav Singh ...
4
2384
by: laktofil | last post by:
This may seem like an abstract question on behavioral inheritance. Anyway, I'm building a hierarchical state machine in C++ (with gcc for target platform Gentoo Linux). More precisely, I'm using this...
0
7057
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7102
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
6756
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
7003
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
1
4798
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
3008
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
1310
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
570
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
199
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.