home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / CLIPPER / MISC / MAILBOX.ZIP / MPTSK.C < prev    next >
Encoding:
C/C++ Source or Header  |  1988-06-27  |  6.1 KB  |  155 lines

  1. /****************************************************************************/
  2. /* mptsk.c  -- MAIL BOX MULTITASKING CLUSTER        (IMPLEMENTATION)    */
  3. /* Created:  12/12/87        Release:  0.7        Version: 06/27/88   */
  4. /****************************************************************************
  5. (c) Copyright 1987, 1988 by Michael Benjamin Parker     (USA SS# 557-49-4130)
  6.  
  7. All Rights Reserved unless specified in the following include files: */
  8. #include "mptsk.cpy" /*
  9.  
  10. DO NOT REMOVE OR ALTER THIS NOTICE AND ITS PROVISIONS.
  11. ****************************************************************************/
  12. /* OVERVIEW:    See mptsk.h                            */
  13. /****************************************************************************/
  14. /****************************************************************************/
  15. #include "mptsk.h"
  16. #include "mpsem.h"
  17. /****************************************************************************/
  18. /****************************************************************************/
  19. /* SUGGESTED TASK PRIORITY SCHEDULE                        */
  20. MPSCD    mpscd_emergencytasks[1];
  21. MPSCD    mpscd_timecriticaltasks[1];
  22. MPSCD    mpscd_interactivetasks[1];
  23. MPSCD    mpscd_backgroundtasks[1];
  24. MPSCD    mpscd_batchtasks[1];
  25. MPSCD    mpscd_idletasks[1];
  26. /****************************************************************************/
  27. MPTSKID    _mptsk_me;
  28. MPTSK    _mptsk_main[1];
  29. /****************************************************************************/
  30. #define    mptsk_mpmsg(mptsk)    ((mptsk)->mpmsg)
  31. #define    mptsk_mympmsg()        (mptsk_mpmsg(mptsk_me()))
  32. #define    mptsk_recvside        (BOOL_FALSE)
  33. #define    mptsk_sendside        (BOOL_TRUE)
  34. /****************************************************************************/
  35. /****************************************************************************/
  36. /****************************************************************************/
  37. void    mptsk_setup()
  38. {
  39.     mpscd_init(mpscd_emergencytasks);
  40.     mpscd_init(mpscd_timecriticaltasks);
  41.     mprng_twistnn(mpscd_emergencytasks,mpscd_timecriticaltasks);
  42.     mpscd_init(mpscd_interactivetasks);
  43.     mprng_twistnn(mpscd_timecriticaltasks,mpscd_interactivetasks);
  44.     mpscd_init(mpscd_backgroundtasks);
  45.     mprng_twistnn(mpscd_interactivetasks,mpscd_backgroundtasks);
  46.     mpscd_init(mpscd_batchtasks);
  47.     mprng_twistnn(mpscd_backgroundtasks,mpscd_batchtasks);
  48.     mpscd_init(mpscd_idletasks);
  49.     mprng_twistnn(mpscd_batchtasks,mpscd_idletasks);
  50.  
  51.     mptsk_init(_mptsk_main,mpthd_me(),mpscd_toptasks());
  52.     mptsk_me()=    mpbox_xfer(mpscd_toptasks(),mptsk_sendside,(MPMSGID)0);
  53.     mptsk_mywaitingfor()=    0;
  54.     mpbug_valp(mptsk_me());
  55. }
  56. /****************************************************************************/
  57. /****************************************************************************/
  58. /****************************************************************************/
  59. MPTSKID    mptsk_init(buf,mpthd,mpscd)
  60.     VOIDPTR    buf;
  61.     MPTHDID    mpthd;
  62.     MPSCDID    mpscd;
  63. {
  64.     MPTSKID    mptsk=    (MPTSKID)buf;
  65.  
  66.     if (!mpthd || !mptsk)    return(0);
  67.     mptsk_mpthd(mptsk)=    mpthd;
  68.     mptsk_mpmsg(mptsk)=    0;
  69.     mprng_init(str2fld(mptsk,_mpmsg));
  70.     mpbox_init(mptsk_mpbox(mptsk));
  71.     mptsk_mpscd(mptsk)=    mpscd;
  72.     mptsk_waitingfor(mptsk)=mpscd;
  73.     mpbox_xfer(mpscd,mptsk_recvside,mptsk);
  74.     mprng_init(mptsk_owns(mptsk));
  75. /*    mpbox_printall(mpscd);
  76. */    mpbug_lev();mpbug_valp(mpthd);mpbug_valp(mptsk);
  77.     return(mptsk);
  78. }
  79. /****************************************************************************/
  80. void PTR    mptsk_dinit(mpscd)
  81.     MPSCDID    mpscd;
  82. {
  83.     MPTSKID    mptsk=    mpbox_xfer(mpscd,mptsk_sendside,(MPRNGID)0);
  84.     if (mptsk) {
  85.         mprng_dinit(str2fld(mptsk,_mpmsg));
  86.         mpbox_dinit(mptsk_mpbox(mptsk));
  87.         mprng_dinit(mptsk_owns(mptsk));
  88. /*        mpthd_dinit(mptsk_mpthd(mptsk));*/
  89.         return(mptsk);
  90.     } else    return(0);
  91. }
  92. /****************************************************************************/
  93. /****************************************************************************/
  94. /* THE mptsk_xfer() FUNCTION    - FOR TRANSFERING MSGS & CTRL BETWEEN TASKS */
  95. /****************************************************************************/
  96. MPMSGID    mptsk_xfer(MPBOXID mpbox, MPMSGID mpmsg, BOOL block, MPSCDID mpscd)
  97. {
  98. /* mpbox_printall(mpscd);
  99. */mpsig_critsect( do {  /* DISABLE INTERRUPTS */
  100.     mptsk_mympthd()=    mpthd_me();
  101. /*SEND*/if (mpmsg) {    /* IF SENDING A MESSAGE */
  102.         MPTSKID    mptsk;
  103.         mptsk=    mpbox_xfer(mpbox,    /* QUEUE MSG <XOR> GET TSK */
  104.                 mptsk_sendside,(MPMSGID)(block?mpmsg:(MPMSGID)0));
  105.         if (mptsk) {    /* A TASK WAS WAITING */
  106.             /* TRANSFER MESSAGE */
  107.              mptsk_mpmsg(mptsk)= mpmsg;    mpmsg= 0;
  108.             /* SCHEDULE BOTH TASKS */
  109.             mpbox_xfer(mptsk_waitingfor(mptsk)=mptsk_mpscd(mptsk),
  110.                 mptsk_recvside,mptsk);
  111.             mpbox_xfer(mptsk_mywaitingfor()=   mptsk_mympscd(),
  112.                 mptsk_recvside,mptsk_me());
  113.         } else {
  114.             if (block) mpmsg=0;    /* MESSAGE SENT */
  115.             break;            /* RETURN IMMEDIATELY */
  116.         }
  117.  
  118. /*RECV*/} else {    /* IF RECEIVING A MESSAGE */
  119.         mpmsg=    mpbox_xfer(    /* GET MSG <XOR> QUEUE TSK */
  120.                 mptsk_mywaitingfor()= mpbox,
  121.                 mptsk_recvside, (MPMSGID)(block?mptsk_me():0));
  122.         if (mpmsg)    break;    /* MESSAGE RECVED: RET IMMEDIATELY */
  123.         if (!block)    break;    /* DON'T WAIT FOR MSG: RET IMMDLY */
  124.     }
  125. /*SCHD*/{    /* SCHEDULE A NEW TASK TO RUN */
  126.         MPTSKID    mptsk;
  127.         MPSCDID    curmpscd=    mpscd;    /* USE USER SCHED LIST */
  128.         /* SEARCH FROM HIGHEST TO LOWEST PRIORITY 'TILL TASK FOUND */
  129.         while (!(mptsk= mpbox_xfer(curmpscd,mptsk_sendside,
  130.                                 (MPMSGID)0))){
  131.             curmpscd=    mprng_next(curmpscd);
  132.             if (curmpscd==mpscd)    /* IF END OF USER SCHED LIST*/
  133.                 curmpscd=  mpscd_toptasks(); /* USE SYS LST */
  134.         }
  135.         mptsk_mympmsg()=mpmsg;    /* SAVE MESSAGE BETWEEN SWITCHES */
  136.         mpbug_lev();    mpbug_valp(mptsk);
  137.         if (!mpthd_switch(mptsk_mpthd(mptsk_me()= mptsk))) {
  138.             fprintf(stderr,
  139.                 "\nmptsk_xfer(%lX,%lX,%d,%lX): FATAL ERROR!",
  140.                 ptr_2int(mpbox),ptr_2int(mpmsg),(int)block,
  141.                 ptr_2int(mpscd));
  142.             fprintf(stderr,
  143. "\nAttempt to switch to the the corrupted mpthd %lX of mptsk %lX. Exiting!\n",
  144.                 ptr_2int(mptsk_mpthd(mptsk)),mptsk);
  145.             exit(-1);
  146.         }
  147.         mpmsg=        mptsk_mympmsg();/* RETURN RESULT MESSAGE */
  148.     }
  149. } while (0);
  150. mptsk_mywaitingfor()=    0;);
  151. return(mpmsg);
  152. }
  153. /****************************************************************************/
  154. /****************************************************************************/
  155.