Function Pointers and Cooperative Multitasking

download Function Pointers and Cooperative Multitasking

of 5

Transcript of Function Pointers and Cooperative Multitasking

  • 8/13/2019 Function Pointers and Cooperative Multitasking

    1/5

    2/19/13 Function Pointers and Cooperative Multitasking

    beej.us/blog/data/function-pointers-cooperative-multitasking/ 1/5

    Beej's Bit BucketBeej's Bit Bucket Tech and Programming Fun Tech and Programming Fun

    A manatee very quickly performshis "float" task before voluntarily

    returning control to the cooperativemultitasking system.

    Function Pointers and Cooperative MultitaskingFunction Pointers and Cooperative Multitasking

    In the Good Old Days of Mac OS 9 and Windows 3.1 , thereexisted a notion of multitasking known as cooperativemultitasking . This is when the OS schedules tasks to run,and gives the tasks complete control of the CPU for as longas they want it. Tasks would voluntarily relinquish controlafter not too long, so that other tasks could run.

    Of course, a greedy task could just take over the systemand not let anything else run, but such a task would lead toan unpleasant user experience, and so such software wasunpopular. In other words, it was in the software's bestinterest to be cooperative.

    Not could greedy tasks take over the sys tem, b ut b uggyones could, as well! This would lead t o system hangs , and user unhappiness. Realcomputer operating syst ems , like Unix, BSD , and Linux, shunned cooperativemultitasking and instead use d the supe rior idea of preemptive multitasking , in which theOS forcibly takes control away from a process when that process's time is up... no morehangs! All modern desktop OSes, including those from Microsoft and Apple , have leftcooperative multitasking behind.

    So why even talk about it at all? Well, it's a good way to bring up another idea in C :function pointers .

    In an earlier article, I talked about pointers in C , which are variables that hold thememory address of other variables. He re's the fun bit: they can hold the memoryaddr ess of funct ions, too! And then yo u can call functions indirectly via the pointer to thefunction!

    What's we're going is use this to set up a little cooperative multitasking system.

    But first let's get through some of the funky C syntax. We'll need to declare a variablethat's of type "pointer to a function". We'll even be specific, and de clare it to be apointer to a function with a certain return type and a certain parameter list. E.g. "Declarea variable named 'functionpointer' that is a pointer to a function that returns an int and

    takes aconst char*

    as a parameter:

    At this point, we've declared a variable named " functionpointer ", but it doesn'tactually point at anything.

    Now for comparison, here is a function prototype for a function that returns anint* :

    2010-01-29

    int (* functionpointer )(const char *s); // this is a function pointer

    int * functionprototype (const char *s); // function prototype!!

    TweetTweet 0 0 1Like 0

    http://en.wikipedia.org/wiki/Function_pointerhttp://en.wikipedia.org/wiki/Windows_7http://en.wikipedia.org/wiki/OS_Xhttp://en.wikipedia.org/wiki/Preemptive_multitaskinghttp://en.wikipedia.org/wiki/Preemptive_multitaskinghttp://en.wikipedia.org/wiki/Preemptive_multitaskinghttp://en.wikipedia.org/wiki/Unixhttp://en.wikipedia.org/wiki/BSDhttp://en.wikipedia.org/wiki/Linuxhttp://en.wikipedia.org/wiki/Linuxhttp://en.wikipedia.org/wiki/Linuxhttp://en.wikipedia.org/wiki/Hang_(computing)http://en.wikipedia.org/wiki/Cooperative_multitasking#Cooperative_multitasking.2Ftime-sharinghttp://en.wikipedia.org/wiki/Nostalgiahttp://en.wikipedia.org/wiki/Mac_OS_9http://en.wikipedia.org/wiki/Windows_3.1http://beej.us/blog/http://beej.us/blog/data/function-pointers-cooperative-multitasking/#http://beej.us/blog/data/function-pointers-cooperative-multitasking/#http://twitter.com/search?q=http%3A%2F%2Fbeej.us%2Fblog%2Fdata%2Ffunction-pointers-cooperative-multitasking%2Fhttps://twitter.com/intent/tweet?original_referer=http%3A%2F%2Fbeej.us%2Fblog%2Fdata%2Ffunction-pointers-cooperative-multitasking%2F&text=Function%20Pointers%20and%20Cooperative%20Multitasking%3A&tw_p=tweetbutton&url=http%3A%2F%2Fbeej.us%2Fblog%2Fdata%2Ffunction-pointers-cooperative-multitasking%2F%23.USMbOXBVkb4.twitterhttp://en.wikipedia.org/wiki/Function_prototypehttp://beej.us/blog/data/c-pointers/http://en.wikipedia.org/wiki/Function_pointerhttp://en.wikipedia.org/wiki/C_(programming_language)http://en.wikipedia.org/wiki/OS_Xhttp://en.wikipedia.org/wiki/Windows_7http://en.wikipedia.org/wiki/Preemptive_multitaskinghttp://en.wikipedia.org/wiki/Linuxhttp://en.wikipedia.org/wiki/BSDhttp://en.wikipedia.org/wiki/Unixhttp://en.wikipedia.org/wiki/Hang_(computing)http://en.wikipedia.org/wiki/Operating_systemhttp://en.wikipedia.org/wiki/Cooperative_multitasking#Cooperative_multitasking.2Ftime-sharinghttp://en.wikipedia.org/wiki/Windows_3.1http://en.wikipedia.org/wiki/Mac_OS_9http://en.wikipedia.org/wiki/Nostalgiahttp://en.wikipedia.org/wiki/Manateehttp://beej.us/blog/
  • 8/13/2019 Function Pointers and Cooperative Multitasking

    2/5

    2/19/13 Function Pointers and Cooperative Multitasking

    beej.us/blog/data/function-pointers-cooperative-multitasking/ 2/5

    Note the subtle difference: the parentheses. This lets the compiler know thatthe * is associated with the functionpointer , and not the int before it.

    So let's blow out this example into something big, and actually have thefunctionpointer point to a function, and then let's call it. The reason I made it returnint and take the const char* parameter was so that it would match another standardfunction in stdio.h , namely puts() this function prints a string on the console . We'llget the address of puts() , store it in functionpointer , and then call it.

    To get the address of a function, you refer to it by name without parentheses. That is,puts("Hello!") calls the function normally, but puts is a pointer to the function. (Youcan preface it with ampersand i f you want (" &puts "), but that's not idiomatic .) So we canstore a pointer to puts() in functionpointer just with the simple assignment:

    Now how do we call the function pointed to by the pointer? That is, how do we call

    puts() via functionpointer ? Easy! We just add parenthesis and arguments and call itlike a normal function:

    And here's a full-blown example of the above stuff:

    Of course, all this so far have been for illustrative purposes and is marginally useful atbest.

    Something in C that's actually common is to use function pointers in the libraryfunctions qsort() and bsearch() . These functions accept as a parameter apointer to a comparison function, which compares two values and returns theresult. The qsort() function uses the results of the comparison function to helpsort an array. The advantage of this approach is that qsort() 's behavior can

    int (* functionpointer )(const char *s); // function pointer

    functionpointer = puts; // functionpointer now points to puts

    functionpointer("Hello, world!"); // just like puts("Hello, world!")

    #include

    int main(void){

    // declare a variable named "functionpointer" that is a pointer to a // function that returns and int and takes one parameter: a const // char *:

    int (* functionpointer )(const char *s);

    // initialize functionpointer to point to the built-in puts() // function:

    functionpointer = puts;

    // now call the function via the pointer:

    functionpointer ("This is just like calling puts()!");

    return 0;}

    C

    http://en.wikipedia.org/wiki/Comparison_sorthttp://en.wikipedia.org/wiki/Bsearchhttp://en.wikipedia.org/wiki/Qsorthttp://en.wikipedia.org/wiki/Idiomhttp://en.wikipedia.org/wiki/System_consolehttp://en.wikipedia.org/wiki/String_(computer_science)http://en.wikipedia.org/wiki/Stdio.h
  • 8/13/2019 Function Pointers and Cooperative Multitasking

    3/5

    2/19/13 Function Pointers and Cooperative Multitasking

    beej.us/blog/data/function-pointers-cooperative-multitasking/ 3/5

    be modified by passing it pointers to different comparison functions, and ageneralized qsort() routine that can sort arbitrary types of data can beshipped for everyone to use.

    For instance, here is a program that sorts arrays. One array is sorted forward,and one is sorted backward. The only difference in the qsort() call is thecomparison function used:

    Anyway, where were we? Oh yeahlet's see if we can use this to set up a simplecooperative multitasking system. The basic idea here is that we're going to have abunch of "tasks", and each task will have an associated function that does all the workof that task. Each function will be called in turn, and each function is expected to returnbefore too much time has elapsed (so it doesn't hog the system).

    We'll have a structure called tasklist that knows how many active tasks there are, andknows which functions are associated with those tasks. How many tasks is easy: it's anint . But we have to have a list of functions for each task... a list of pointers to functions...an array of pointers functions... an array of pointers to functions that return void andhave no parameters. Man, how do you declare that?

    Again the syntax is funky, but it is what it is . Here's an example declaration of an arrayof pointers to functions, with 10 elements:

    There we've declared an array of pointers to functions, and that array is named"task_function ". Here's an assignment to the third array element (index 2) and a

    #include

    #include

    int sort_ascending (const void *a, const void *b){ return *(int*)a > *(int*)b;}

    int sort_descending (const void *a, const void *b){ return *(int*)a < *(int*)b;}

    int main(void){ int array1[5] = { 9, 2, 6, 1, 7 }; int array2[5] = { 9, 2, 6, 1, 7 };

    // give qsort() a pointer to the "sort_ascending" // comparison function:

    qsort(array1, 5, sizeof(int), sort_ascending );

    // give qsort() a pointer to the "sort_descending" // comparison function:

    qsort(array2, 5, sizeof(int), sort_descending );

    return 0;}

    C

    void (*task_function[10])(void);

    http://en.wikipedia.org/wiki/Law_of_identity
  • 8/13/2019 Function Pointers and Cooperative Multitasking

    4/5

    2/19/13 Function Pointers and Cooperative Multitasking

    beej.us/blog/data/function-pointers-cooperative-multitasking/ 4/5

    subsequent call to it:

    For this final example, we'll make up three tasks: one for Manatees , one for Goats , andone for Bats . Each task's function does a short thing and then returns control so it cango on to the next function. In main() the task list is initialized with three tasks, and thetask function pointers are stored in the task function pointer array.

    The main loop then runs through the task list and dispatches each one in order, andthen starts over again, round-robin style. In this example, it does it forever, but that's justmy arbitrary decision.

    And this gives the following output:

    task_function[2] = foo; // assign to point to function footask_function[2](); // call it (call foo(), that is)

    #include

    #define MAX_TASKS 10

    struct tasklist { int task_count; void (*task_function[MAX_TASKS])(void);};

    void manatee_float_and_graze (void){ printf(" The manatee is floating and grazing.\n");}

    void goat_stand_on_item (void){ printf(" The goat is standing on an item.\n");}

    void bat_eat_insects (void){ printf(" The bat is eating insects.\n");}

    int main(void){ int i; struct tasklist tl;

    tl.task_count = 3; tl.task_function[0] = manatee_float_and_graze ; tl.task_function[1] = goat_stand_on_item ; tl.task_function[2] = bat_eat_insects ;

    while (1) { printf ("Dispatching:\n"); for (i = 0; i < tl.task_count; i++) { tl.task_function[i](); // execute the task's function } }

    return 0;}

    C

    Dispatching: The manatee is floating and grazing. The goat is standing on an item.

    http://en.wikipedia.org/wiki/Round-robin_schedulinghttp://en.wikipedia.org/wiki/Scheduling_(computing)#Dispatcherhttp://en.wikipedia.org/wiki/Bathttp://en.wikipedia.org/wiki/Goathttp://en.wikipedia.org/wiki/Manatee
  • 8/13/2019 Function Pointers and Cooperative Multitasking

    5/5

    2/19/13 Function Pointers and Cooperative Multitasking

    beej.us/blog/data/function-pointers-cooperative-multitasking/ 5/5

    Blog Email [email protected] Home page

    TweetTweet 0 0 1

    Ways to improve this might be to pass a pointer to a data chunk to each task so it couldmaintain some state between calls. Or you could choose a different schedulingalgorithm that would call tasks in an order other than round-robin. Or you could allow thesystem to dynamically create and destroy tasks as needed.

    For fun sometime in the future I might write a piece on scheduling and priorities and soon.

    Share me!Share me!

    Historic CommentsHistoric Comments

    Show

    CommentsComments

    0 comments

    Leave a message...

    DiscussionDiscussion CommunityCommunity

    ShareShare

    1

    The bat is eating insects.Dispatching: The manatee is floating and grazing. The goat is standing on an item. The bat is eating insects.Dispatching: The manatee is floating and grazing. . . . [forever]

    Like 0

    http://beej.us/blog/data/function-pointers-cooperative-multitasking/#http://en.wikipedia.org/wiki/Scheduling_algorithmhttp://en.wikipedia.org/wiki/Program_statehttp://beej.us/blog/data/function-pointers-cooperative-multitasking/#http://beej.us/blog/data/function-pointers-cooperative-multitasking/#http://beejsbitbucket.disqus.com/function_pointers_and_cooperative_multitasking/latest.rsshttp://disqus.com/http://beej.us/blog/data/function-pointers-cooperative-multitasking/#http://beej.us/blog/data/function-pointers-cooperative-multitasking/#http://beej.us/blog/data/function-pointers-cooperative-multitasking/#http://beej.us/blog/data/function-pointers-cooperative-multitasking/#http://beej.us/blog/data/function-pointers-cooperative-multitasking/#http://beej.us/blog/data/function-pointers-cooperative-multitasking/#http://twitter.com/search?q=http%3A%2F%2Fbeej.us%2Fblog%2Fdata%2Ffunction-pointers-cooperative-multitasking%2Fhttps://twitter.com/intent/tweet?original_referer=http%3A%2F%2Fbeej.us%2Fblog%2Fdata%2Ffunction-pointers-cooperative-multitasking%2F&text=Function%20Pointers%20and%20Cooperative%20Multitasking%3A&tw_p=tweetbutton&url=http%3A%2F%2Fbeej.us%2Fblog%2Fdata%2Ffunction-pointers-cooperative-multitasking%2F%23.USMbOaFXLH4.twitterhttp://beej.us/mailto:[email protected]://beej.us/blog/