home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #31 / NN_1992_31.iso / spool / comp / sys / amiga / programm / 17722 < prev    next >
Encoding:
Text File  |  1992-12-22  |  4.3 KB  |  127 lines

  1. Newsgroups: comp.sys.amiga.programmer
  2. Path: sparky!uunet!gatech!concert!samba!usenet
  3. From: Todd_Lewis@unc.edu (Todd M. Lewis)
  4. Subject: Re: task communication and forbid()
  5. Message-ID: <1992Dec22.210606.29689@samba.oit.unc.edu>
  6. Sender: usenet@samba.oit.unc.edu
  7. Nntp-Posting-Host: guitar.oit.unc.edu
  8. Organization: UNC Office of Information Technology
  9. References: <1992Dec18.204844.1796@samba.oit.unc.edu>
  10. Date: Tue, 22 Dec 1992 21:06:06 GMT
  11. Lines: 114
  12.  
  13. In article <1992Dec18.204844.1796@samba.oit.unc.edu> Todd_Lewis@unc.edu (Todd  
  14. M. Lewis) writes:
  15. >Ugh.  That's not good.  You will waste half of your cycles busy-waiting.
  16. >You want to do a for-real Wait().  Some notes on the code that follows.
  17. >  1)  This is off the top of my head--I don't have an Amiga here to
  18. >      test it with, so it may not compile, much less work.
  19.  
  20. Well, I took it home and fixed a few things.  This example compiles
  21. and runs under Manx 5.2a.  Porting to "other platforms" should
  22. be simple.  If you kept the previous post for reference, replace it
  23. with this one.  Nothing major, but it might save you a few minutes.
  24.  
  25. ================== coordinate.c =============================
  26. /********
  27. Some notes on the code that follows.
  28.   1)  This works under Manx 5.2a.  Other C compilers should be easy too.
  29.   2)  The signal SIGF_SINGLE is pre-allocated for every task so if
  30.       you are just waiting on one thing you can use this "well-known signal".
  31.       Always clear it before waiting on it.  That's what simple_wait() is for.
  32.   3)  When you call CreateTask(), you have no way to know if the subtask has
  33.       gotten to run at all by time the call returns, so coordination between
  34.       parent and child tasks is really tricky.
  35.   4)  carefully study the Forbid()/Permit() pairs around the state variable
  36.       examination/change/simple_wait() groups.  Follow both threads of
  37.       execution and at every line in the program ask yourself "What happens
  38.       if a task switch occurs here?"  I think I've considered all the pitfalls.
  39.   5)  This is just an example.  You should make sure a ^C doesn't kill
  40.       the main() task while child() is running.
  41. *********************/
  42.  
  43. #include <exec/tasks.h>
  44. #ifdef AZTEC_C
  45.   #include <functions.h>
  46. #endif
  47.  
  48. #define STARTRUNNING 1
  49. #define RUNNING      2
  50. #define DROPDEAD     3
  51. #define DEAD         4
  52.  
  53. struct Task *mamma_ptr;
  54. struct Task *child_ptr;
  55.  
  56. int             state      = 0;
  57. ULONG           counter    = 0;
  58.  
  59. void simple_wait( void )
  60.   {
  61.     SetSignal( 0L, SIGF_SINGLE );  /* Clear the signal.    */
  62.     Wait( SIGF_SINGLE );           /* Wait for the signal. */
  63.   }
  64.  
  65. void child( void )
  66.   {
  67. #ifdef AZTEC_C
  68.     geta4();
  69. #endif
  70.     Forbid();
  71.       while ( state < STARTRUNNING )
  72.         simple_wait();
  73.     Permit();
  74.  
  75.     Forbid();
  76.       state = RUNNING;
  77.       Signal( mamma_ptr, SIGF_SINGLE);
  78.     Permit();
  79.  
  80.     while( state == RUNNING )  /* Do something wonderful.   */
  81.        counter++;
  82.  
  83.     Forbid();                  /* state should be DROPDEAD. */
  84.       state = DEAD;
  85.       Signal( mamma_ptr, SIGF_SINGLE );
  86.     /* Hanging Forbid() ensures child exits before main() resumes. */
  87.   }
  88.  
  89. int main( int argc, char *argv[] )
  90.   {
  91.     mamma_ptr = FindTask(0);
  92.     child_ptr = CreateTask("the kid", 0, child, 2048 );
  93.  
  94.     if ( child_ptr )
  95.        {
  96.          printf("Child task created.\n");
  97.  
  98.          state = STARTRUNNING; /* Tell child to run some more. */
  99.          Signal( child_ptr, SIGF_SINGLE );
  100.  
  101.          Forbid();             /* Wait for child to start running. */
  102.            while ( state < RUNNING )
  103.              simple_wait();
  104.          Permit();             /* Child is running.       */
  105.  
  106.          printf("Child task is running.\n");
  107.  
  108.          Delay( 250L );        /* Sleep for 5 seconds.    */
  109.                                /* Do something wonderful. */
  110.          printf("Child has counted to %d.\n", counter );
  111.  
  112.          Forbid();
  113.            state = DROPDEAD;   /* Tell child to die.      */
  114.            simple_wait();      /* Wait for child to die.  */
  115.          Permit();
  116.                      /* child (and state) should be DEAD. */
  117.          printf("Child task completed.\n");
  118.          printf("Child has counted to %d.\n", counter );
  119.        }
  120.     return 0;
  121.   }
  122.  
  123. --
  124.  _/_/_/  _/     Todd_Lewis@unc.edu          You can lead a horse to 
  125.   _/    _/     utoddl@guitar.oit.unc.edu   Mohammad, but you can't make
  126.  _/    _/_/_/                             a mountain drink a mole hill.
  127.