home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_08_04 / 8n04117a < prev    next >
Text File  |  1990-03-20  |  3KB  |  92 lines

  1. ***************
  2. ** Listing 3 **
  3. ***************
  4.  
  5. /*
  6.  
  7.   fork_execute() -- Execute the fork queue
  8.  
  9.   This task executes all elements on the fork queue.  While
  10.   the queue is executing, other elements can be place onto
  11.   the queue.
  12.  
  13.   The queue operates by setting up a special TSS to be a
  14.   duplicate of the queued driver's TSS, except for the current
  15.   CS:IP and the stack.  This allows all forked routines to
  16.   execute using the exact same environment it would have if
  17.   the task (or driver) had called the routine directly.
  18.  
  19.   Actually, one enviromental difference may occur.  All
  20.   routines executing on the fork will be run with
  21.   interrupts enabled.
  22.  
  23.   In addition, the forked routine will be called in such a
  24.   manner that all it needs to do is issue a return to exit
  25.   the routine.  The queue will handle the rest.  Any return
  26.   value issued by the forked routine will be ignored. */
  27.  
  28. void fork_execute()
  29.   {
  30.   DWORD fork_addr;
  31.   OFFSET fork_sp;
  32.   SELECTOR fork_ss;
  33.   FORK_PARAM *owner;
  34.   unsigned char current_name[NAME_SIZE + 1];
  35.  
  36.   current_name[NAME_SIZE] = '\0';
  37.  
  38. /* Initialize some constants, such as the base stack, and
  39.    the queue startup routine to use.            */
  40.  
  41.   fork_ss = fdummy_tcb.ss;
  42.   fork_sp = fdummy_tcb.sp;
  43.   fork_addr.whole = (unsigned long) fork_start;
  44.  
  45.   /* Loop to continue task at each invokation */
  46.   while (1)
  47.     {
  48.  
  49.     /* Tell the world that we are running the queue */
  50.     fork_in_process = 1;
  51.  
  52.     /* As long as we have something to do.... */
  53.     while (fork_queue)
  54.       {
  55.       /* Get the next element */
  56.       owner = fork_queue;
  57.       fork_queue = fork_queue -> link;
  58.  
  59.       /* Set up the information for fork_start() */
  60.       current_routine = owner -> routine;
  61.       current_param = owner -> param1;
  62.  
  63.       /* Set up the TSS to give the target routine access
  64.          to the owning task's LDT.  Also, set up for
  65.      interrupts enabled.                */
  66.  
  67.       movemem(owner -> tcb, &fdummy_tcb, 44);
  68.  
  69.       fdummy_tcb.cs = fork_addr.high;
  70.       fdummy_tcb.ip = fork_addr.low;
  71.       fdummy_tcb.ss = fork_ss;
  72.       fdummy_tcb.sp = fork_sp;
  73.       fdummy_tcb.flag_word |= F_IE;
  74.  
  75.       /* Execute task (Task switch) */
  76.       fdummy_task();
  77.  
  78.       /* One less fork fork entry for this driver. */
  79.       ((DSS *) owner -> tcb) -> current_fork_count--;
  80.  
  81.       /* Place used entry back on free list */
  82.       owner -> link = fork_free;
  83.       fork_free = owner;
  84.       fork_count--;
  85.       }
  86.  
  87.     /* Clear fork flag and reschedule */
  88.     fork_in_process = 0;
  89.     resume_cl(scheduler_task);
  90.     }
  91.   }
  92.