home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / CTASK22.ZIP / TSKSUB.C < prev    next >
C/C++ Source or Header  |  1990-10-12  |  5KB  |  219 lines

  1. /*
  2.    --- Version 2.2 90-10-12 10:33 ---
  3.  
  4.    CTask Subroutines
  5.  
  6.    Public Domain Software written by
  7.       Thomas Wagner
  8.       Ferrari electronic Gmbh
  9.       Beusselstrasse 27
  10.       D-1000 Berlin 21
  11.       Germany
  12.  
  13.    Note: The find_xxx_name functions were moved to a separate file,
  14.    'tskname.c', in version 2.1 for potential code savings.
  15. */
  16.  
  17. #include "tsk.h"
  18. #include "tsklocal.h"
  19.  
  20.  
  21. /*
  22.    tsk_runable
  23.       Make a task eligible for running. The task is removed from the
  24.       timer queue and enqueued in the eligible queue.
  25.  
  26.       CAUTION: Critical section assumed entered.
  27. */
  28.  
  29. void Localfunc tsk_runable (tcbptr task)
  30. {
  31.    CHECK_TCBPTR (task, "Task Runable");
  32.  
  33.    task->state = ST_ELIGIBLE;
  34.    tsk_deqtimer (&task->timerq.link);
  35.    tsk_dequeue (&task->cqueue);
  36.    tsk_enqueue (task->qhead = &GLOBDATA eligible_queue, &task->cqueue);
  37. }
  38.  
  39.  
  40. /*
  41.    tsk_run_pending
  42.       Make a task eligible for running, but don't enqueue it in the
  43.       eligible queue.
  44.  
  45.       CAUTION: Critical section assumed entered.
  46. */
  47.  
  48. void Localfunc tsk_run_pending (tcbptr task)
  49. {
  50.    CHECK_TCBPTR (task, "Task Runable");
  51.  
  52.    task->state = ST_ELIGIBLE;
  53.    tsk_deqtimer (&task->timerq.link);
  54.    tsk_dequeue (&task->cqueue);
  55. }
  56.  
  57.  
  58. /*
  59.    tsk_runable_all
  60.       Make all tasks in a queue eligible for running.
  61.  
  62.       CAUTION: Critical section assumed entered.
  63. */
  64.  
  65. void Localfunc tsk_runable_all (queheadptr que)
  66. {
  67.    queptr curr;
  68.    tcbptr task;
  69.  
  70.    CHECK_QHEAD (que, "Task Runable All: Queue");
  71.  
  72.    for (curr = que->first; !(curr->kind & Q_HEAD); )
  73.       {
  74.       task = (tcbptr)curr;
  75.       CHECK_TCBPTR (task, "Task Runable All: TCB");
  76.       curr = curr->next;
  77.       task->state = ST_ELIGIBLE;
  78.       tsk_deqtimer (&task->timerq.link);
  79.       tsk_enqueue (task->qhead = &GLOBDATA eligible_queue, &task->cqueue);
  80.       }
  81.    tsk_init_qhead (que, que->kind);
  82. }
  83.  
  84.  
  85. /*
  86.    tsk_wait
  87.       put current running task in wait state.
  88.  
  89.       With version 2.2, the wait action was changed to immediately
  90.       enqueue the task into the respective queue. In previous versions,
  91.       the task was not enqueued, this was done by the scheduler based 
  92.       on the queue head pointer. Starting with version 2.1, interrupts 
  93.       are enabled early in the scheduler, before the scheduler gets to 
  94.       the point where it enqueues the task. This could lead to race 
  95.       conditions, with tasks being only partially enqueued, or never 
  96.       dequeued, when "tsk_runable" was called by an interrupt handler
  97.       hitting in this interval.
  98.  
  99.       CAUTION: Critical section assumed entered.
  100. */
  101.  
  102. void Localfunc tsk_wait (queheadptr que, dword timeout)
  103. {
  104.    tcbptr curr;
  105.  
  106.    /*
  107.       Note: The following test shouldn't be necessary. However,
  108.       if ever an interrupt handler should cause the current task to
  109.       be made waiting while the scheduler is active, this would cause
  110.       catastrophic effects (also see the notes in tskasm.asm).
  111.       Well, no interrupt handler should ever do such a nasty thing, but...
  112.       So if the in_sched flag is set, we have to stop everything.
  113.       The test is ommitted when we're not running under DOS.
  114.    */
  115.  
  116. #if (DOS || DEBUG)
  117.    if (GLOBDATA in_sched)
  118.       tsk_fatal ("Wait while in Scheduler");
  119. #endif
  120.  
  121.    CHECK_QHEAD (que, "Task Wait: Queue");
  122.  
  123.    curr = GLOBDATA current_task;
  124.    curr->state = ST_WAITING;
  125.    tsk_enqueue (curr->qhead = que, &curr->cqueue);
  126.    if (timeout)
  127.       {
  128.       tsk_enqtimer (&curr->timerq.link, timeout);
  129.       curr->timerq.flags = 0;
  130.       curr->timerq.link.kind = TYP_TIMER;
  131.       }
  132.    schedule ();
  133. }
  134.  
  135.  
  136. #if (TSK_NAMED)
  137.  
  138. /*
  139.    tsk_copy_name
  140.       A replacement for strcpy, used for copying names. The C-runtime
  141.       strcpy is not used here to keep the kernel model independent.
  142. */
  143.  
  144. void Localfunc tsk_copy_name (nameptr elem, byteptr name)
  145. {
  146.    byteptr n;
  147.    int i;
  148.  
  149.    n = elem->name;
  150.    if (name != LNULL)
  151.       for (i = 0; i < 8; i++)
  152.          if ((*n++ = *name++) == 0)
  153.             break;
  154.    *n = 0;
  155. }
  156.  
  157.  
  158. /*
  159.    tsk_add_name
  160.       Initialise name-list element and insert it into the name list.
  161.       NOTE: no check is made for duplicate names; names are not sorted.
  162.       Version 2.1 allows name pointers to be LNULL. Structures with LNULL
  163.       name pointers are not added to the list.
  164. */
  165.  
  166. void Localfunc tsk_add_name (nameptr elem, byteptr name, byte kind, farptr strucp)
  167. {
  168.    CRITICAL;
  169.  
  170.    elem->list.kind = kind;
  171.    elem->strucp = strucp;
  172.    if (name == LNULL)
  173.       {
  174.       elem->list.first = LNULL;
  175.       elem->name [0] = 0;
  176.       return;
  177.       }
  178.  
  179.    tsk_copy_name (elem, name);
  180.  
  181.    C_ENTER;
  182. #if (GROUPS)
  183.    tsk_putqueue (&GLOBDATA current_task->group->namelist.list, (queptr)&elem->list);
  184. #else
  185.    tsk_putqueue (&GLOBDATA name_list.list, (queptr)&elem->list);
  186. #endif
  187.    C_LEAVE;
  188. }
  189.  
  190.  
  191. /*
  192.    tsk_del_name
  193.       delete name-element from the name-list.
  194. */
  195.  
  196. void Localfunc tsk_del_name (nameptr elem)
  197. {
  198.    CRITICAL;
  199.  
  200.    C_ENTER;
  201.    tsk_dequeue ((queptr)&elem->list);
  202.    C_LEAVE;
  203. }
  204.  
  205. #endif
  206.  
  207.  
  208. /*
  209.    tsk_init_qhead
  210.       Initializes the head of a queue.
  211. */
  212.  
  213. void Localfunc tsk_init_qhead (queheadptr head, byte kind)
  214. {
  215.    head->kind = Q_HEAD | kind;
  216.    head->first = head->last = (queptr)head;
  217. }
  218.  
  219.