home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / comp / sys / amiga / programm / 17544 < prev    next >
Encoding:
Text File  |  1992-12-21  |  4.2 KB  |  123 lines

  1. Newsgroups: comp.sys.amiga.programmer
  2. Path: sparky!uunet!stanford.edu!rock!concert!samba!usenet
  3. From: Todd_Lewis@unc.edu (Todd M. Lewis)
  4. Subject: Re: task communication and forbid()
  5. Message-ID: <1992Dec18.204844.1796@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.055155.18152@umr.edu>
  10. Date: Fri, 18 Dec 1992 20:48:44 GMT
  11. Lines: 110
  12.  
  13. In article <1992Dec18.055155.18152@umr.edu> quandt@mcs213b.cs.umr.edu (Brian  
  14. Quandt) writes:
  15. >I have a question on how to communicate from a subtask to the parent.
  16. >The main problem is that I need to call forbid so that I can
  17. >ensure that I get timely response during the while loop.  Is it
  18. >legit to use globals?  Is there any special way that these
  19. >globals need to be declared (memory model) ?  I know that task
  20. >communication via globals and assumed constant memory addresses
  21. >is ugly but it seems to be the correct way on the amiga.  Is it?
  22. >Is there a better way? 
  23. > {
  24. > CreateTask( some task that reads keyboard input and sets globalKILL
  25. >         appropriatly )
  26. > forbid();
  27. > while(!globalKILL)
  28. >    {
  29. >        
  30. >     }
  31. > permit();
  32. > }
  33.  
  34. Ugh.  That's not good.  You will waste half of your cycles busy-waiting.
  35. You want to do a for-real Wait().  Some notes on the code that follows.
  36.   1)  This is off the top of my head--I don't have an Amiga here to
  37.       test it with, so it may not compile, much less work.
  38.   2)  The signal SIGF_SINGLE is pre-allocated for every task so if
  39.       you are just waiting on one thing you can use this "well-known signal".
  40.       Always clear it before waiting on it.  That's what simple_wait() is for.
  41.   3)  When you call CreateTask(), you have no way to know if the subtask has
  42.       gotten to run at all by time the call returns, so coordination between
  43.       parent and child tasks is really tricky.
  44.   4)  carefully study the Forbid()/Permit() pairs around the state variable
  45.       examination/change/simple_wait() groups.  Follow both threads of
  46.       execution and at every line in the program ask yourself "What happens
  47.       if a task switch occurs here?"  I think I've considered all the pitfalls.
  48.  
  49. ================== coordinate.c =============================
  50. #include <exec/tasks.h>
  51.  
  52. #define STARRUNNING 1
  53. #define RUNNING     2
  54. #define DROPDEAD    3
  55. #define DEAD        4
  56.  
  57. struct Process *mamma_ptr;
  58. struct Process *child_ptr;
  59. int             state      = 0;
  60. ULONG           counter    = 0;
  61.  
  62. void simple_wait( void )
  63.   {
  64.     SetSignal( 0L, SIGF_SINGLE );  /* Clear the signal.    */
  65.     Wait( SIGF_SINGLE );           /* Wait for the signal. */
  66.   }
  67.  
  68. void child( void )
  69.   {
  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 = CreatTask("the kid", 0, child, 2048 );
  93.     if ( child_ptr )
  94.        {
  95.          state = STARTRUNNING; /* Tell child to run some more. */
  96.          Signal( child_ptr, SIGF_SINGLE );
  97.  
  98.          Forbid();             /* Wait for child to start running. */
  99.            while ( state < RUNNING )
  100.              simple_wait();
  101.          Permit();             /* Child is running.       */
  102.  
  103.          Delay( 250L );        /* Sleep for 5 seconds.    */
  104.                                /* Do something wonderful. */
  105.          Forbid();
  106.            state = DROPDEAD;   /* Tell child to die.      */
  107.            simple_wait();      /* Wait for child to die.  */
  108.          permit();
  109.                      /* child (and state) should be DEAD. */
  110.        }
  111.     return 0;
  112.   }
  113. =====================================================================
  114.  
  115. --
  116.  _/_/_/  _/     Todd_Lewis@unc.edu          You can lead a horse to 
  117.   _/    _/     utoddl@guitar.oit.unc.edu   Mohammad, but you can't make
  118.  _/    _/_/_/                             a mountain drink a mole hill.
  119.