home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / misc / amigem.lha / amigem / exec / tasks.c < prev   
Encoding:
C/C++ Source or Header  |  1995-01-30  |  5.4 KB  |  229 lines

  1. #include <exec/tasks.h>
  2. #include <exec/memory.h>
  3. #include <stdio.h>
  4. #include <amigem/utils.h>
  5. #include <clib/_exec.h>
  6. #include "exec.h"
  7.  
  8. #include <amigem/fd_lib.h>
  9. #define LIBBASE struct ExecBase *SysBase
  10.  
  11. #define FallAsleep     Private_1
  12. #define SwitchContext    Private_2
  13. #define AddContext    Private_3
  14. #define DISPATCH()    Cause(SysBase->SoftDispatch)
  15.  
  16. #define DISPATCH_PENDING 1
  17.  
  18. FD0F(22,p,void,Forbid)
  19. {
  20.   SysBase->TDNestCnt++;
  21. }
  22.  
  23. FD0F(23,p,void,Permit)
  24. {
  25.   if(!SysBase->TDNestCnt--&&SysBase->SysFlags&DISPATCH_PENDING)
  26.     DISPATCH();
  27. }
  28.  
  29. FC1F(0,d,void,UserTask,A0,struct ExecBase *SysBase,A6)
  30. ;
  31.  
  32. FC2F(0,b,void,NewTask,A5,APTR is_data,A1,struct ExecBase *SysBase,A6)
  33. {
  34.   APTR *buf=(APTR *)is_data;
  35.   Enable(); /* Called in disabled state */
  36.   UserTask(buf[0],SysBase);
  37.   if(buf[1]!=NULL)
  38.     UserTask(buf[1],SysBase);
  39.   else
  40.     RemTask(0);
  41. }
  42.  
  43. FD3(47,APTR,AddTask,struct Task *task,A1,APTR initialPC,A2,APTR finalPC,A3)
  44. {
  45.   APTR *buf;
  46.   if(!task->tc_Node.ln_Type)
  47.     task->tc_Node.ln_Type=NT_TASK;
  48.   if(!task->tc_Node.ln_Name)
  49.     task->tc_Node.ln_Name="unknown task";
  50.   task->tc_State=TS_READY;
  51.   if(!task->tc_SigAlloc)
  52.     task->tc_SigAlloc=0xffff;
  53.   /* exceptions & traps */
  54.   if(!task->tc_SPReg)
  55.     task->tc_SPReg=STACKPOINTER(task->tc_SPLower,task->tc_SPUpper);
  56.   /* switch & launch */
  57.   buf=(APTR *)ALLOCONSTACK(&task->tc_SPReg,2*sizeof(APTR));
  58.   buf[0]=initialPC;
  59.   buf[1]=finalPC;
  60.   task->tc_SPReg=AddContext(task->tc_SPReg,&__NewTask,buf);
  61.   task->tc_State=TS_READY;
  62.   Disable();
  63.     Enqueue(&SysBase->TaskReady,&task->tc_Node);
  64.     DISPATCH();
  65.   Enable();
  66.   return task;
  67. }
  68.  
  69. FD1(48,void,RemTask,struct Task *task,A1)
  70. {
  71.   Forbid(); /* The following may free the task structure */
  72.   {
  73.     struct MemList *mb; /* Free all memory */
  74.     struct Task *t=(task==NULL?SysBase->ThisTask:task);
  75.     while((mb=(struct MemList *)RemHead(&t->tc_MemEntry))!=NULL)
  76.     {
  77.       FreeEntry(mb);
  78.       FreeMem(mb,sizeof(struct MemList)-sizeof(struct MemEntry)+
  79.                  mb->ml_NumEntries*sizeof(struct MemEntry));
  80.     }
  81.     Disable();
  82.       if(!task) /* cannot remove myself - let the dispatcher do it */
  83.       {
  84.         t->tc_State=TS_REMOVED;
  85.         DISPATCH();
  86.         SysBase->TDNestCnt=-1;
  87.         SysBase->IDNestCnt=0;
  88.         Enable();
  89.         for(;;) /* Dispatcher could not remove this task */
  90.           FallAsleep();
  91.       }
  92.       else
  93.         Remove(&task->tc_Node);
  94.     Enable();
  95.   }
  96.   Permit();
  97. }
  98.  
  99. FD2(50,BYTE,SetTaskPri,struct Task *task,A1,long pri,D0)
  100. {
  101.   BYTE old;
  102.   Disable();
  103.     old=task->tc_Node.ln_Pri;
  104.     task->tc_Node.ln_Pri=pri;
  105.     if(task->tc_State!=TS_WAIT)
  106.     {
  107.       if(task!=SysBase->ThisTask)
  108.       { Remove(&task->tc_Node);
  109.         Enqueue(&SysBase->TaskReady,&task->tc_Node); }
  110.       DISPATCH();
  111.     }
  112.   Enable();
  113.   return old;
  114. }
  115.  
  116. FD1(49,struct Task *,FindTask,STRPTR name,A1)
  117.   struct Task *ret;
  118.   if(name==NULL)
  119.     ret=SysBase->ThisTask;
  120.   else
  121.   {
  122.     Disable();
  123.       if((ret=(struct Task *)FindName(&SysBase->TaskReady,name))==NULL)
  124.         if((ret=(struct Task *)FindName(&SysBase->TaskWait,name))==NULL)
  125.         {
  126.           char *s1=SysBase->ThisTask->tc_Node.ln_Name;
  127.           char *s2=name;
  128.           while(*s1++==*s2)
  129.             if(!*s2++)
  130.             { 
  131.               ret=SysBase->ThisTask;
  132.               break;
  133.             }
  134.         }
  135.     Enable();
  136.   }
  137.   return ret;
  138. }
  139.  
  140. FC3(0,ULONG,UserException,A0,ULONG signals,D0,APTR exceptData,A1,struct ExecBase *SysBase,A6)
  141. ;
  142.  
  143. FC2F(0,b,void,ExceptionMode,A5,ULONG sigs,A1,struct ExecBase *SysBase,A6)
  144. {
  145.   struct Task *me=SysBase->ThisTask;
  146.   do
  147.   {
  148.     APTR code,data;
  149.     code=me->tc_ExceptCode;
  150.     data=me->tc_ExceptData;
  151.     Enable(); /* Function is called Disabled */
  152.       sigs=UserException(code,sigs,data,SysBase);
  153.     Disable();
  154.     me->tc_SigExcept|=sigs;
  155.     sigs=me->tc_SigExcept&me->tc_SigRecvd;
  156.     me->tc_SigRecvd &=~sigs;
  157.     me->tc_SigExcept&=~sigs;
  158.   }while(sigs);
  159. }
  160.  
  161. FC2F(0,bi,LONG,Dispatcher,A5,APTR is_data,A1,struct ExecBase *SysBase,A6)
  162. {
  163.   struct Task *t1,*t2;
  164.  
  165.   Disable(); /* Arbitrate for SysBase */
  166.  
  167.   SysBase->SysFlags&=~DISPATCH_PENDING;
  168.  
  169.   t1=SysBase->ThisTask;
  170.   if(t1->tc_State==TS_EXCEPT) /* A task that wants to run in exception mode */
  171.   {
  172.     ULONG sigs;
  173.     sigs=t1->tc_SigExcept&t1->tc_SigRecvd;
  174.     t1->tc_SigRecvd &=~sigs;
  175.     t1->tc_SigExcept&=~sigs;
  176.     SwitchContext(AddContext(SwitchContext(NULL),&__ExceptionMode,(APTR)sigs));
  177.     t1->tc_State=TS_RUN;
  178.     goto end;
  179.   }
  180.  
  181.   t2=(struct Task *)SysBase->TaskReady.lh_Head;
  182.   if(!t2->tc_Node.ln_Succ)
  183.     goto end; /* No ready task - no dispatching */
  184.  
  185.   if(SysBase->TDNestCnt!=-1) /* sceduling disabled */
  186.   { SysBase->SysFlags|=DISPATCH_PENDING;
  187.     goto end; }
  188.  
  189.   switch(t1->tc_State)
  190.   {
  191.     default:  /* illegal task state - treat it as TS_RUN */
  192.     case TS_RUN: /* normal dispatching */
  193.       if(t2->tc_Node.ln_Pri<t1->tc_Node.ln_Pri) /* priority too low */
  194.         goto end;
  195.       Enqueue(&SysBase->TaskReady,&t1->tc_Node);
  196.       t1->tc_State=TS_READY;
  197.       break;
  198.     case TS_WAIT: /* A task that wants to go into the waiting queue */
  199.       Enqueue(&SysBase->TaskWait,&t1->tc_Node);
  200.       break;
  201.     case TS_REMOVED: /* A task that wants to be removed */
  202.       break; /* simply don't feed the waiting queue */
  203.   }
  204.  
  205.   t1->tc_SPReg=SwitchContext(t2->tc_SPReg);
  206.   Remove(&t2->tc_Node);
  207.   SysBase->ThisTask=t2;
  208.   t2->tc_State=TS_RUN;
  209.   SysBase->DispCount++;
  210.  
  211. end:
  212.   Enable();
  213.   return 0;
  214. }
  215.  
  216. /* No documentation available */
  217. FD1(123,void,ChildFree,APTR tid,D0)
  218. {}
  219.  
  220. FD1(124,void,ChildOrphan,APTR tid,D0)
  221. {}
  222.  
  223. FD1(125,void,ChildStatus,APTR tid,D0)
  224. {}
  225.  
  226. FD1(126,void,ChildWait,APTR tid,D0)
  227. {}
  228.