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

  1. /****************************************************************************/
  2. /* mpthd.c - THREAD CLUSTER (IMPLEMENTATION)                    */
  3. /* Created:  10/31/87        Release:  0.7        Version:  06/27/88  */
  4. /****************************************************************************
  5. (c) Copyright 1987 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. #include "mpthd.h"
  13. #define    NDEBUG
  14. #include "mpbug.h"
  15. /****************************************************************************/
  16. MPTHDID    mpthd_me_reg;    /* A DEDICATED "REGISTER" OF THE PROCESSOR POINTING
  17.             TO THE THREAD IT CURRENTLY EXECUTES.
  18.             ON SINGLE-PROCESSOR IMPLEMENTATIONS (AS THIS ONE),
  19.               CAN BE A GLOBAL VARIABLE */
  20. extern    main();        /* THE PROGRAM'S main FUNCTION */
  21. /****************************************************************************/
  22. /****************************************************************************/
  23. void    _mpthd_setup(mpthd)
  24.     MPTHDID    mpthd;
  25. {
  26.     mpthd_me()=    mpthd;
  27.     mpsem_take(str2fld(mpthd_me(),mpsem));
  28. }
  29. /****************************************************************************/
  30. #define    mpthd_mainmpthds    10
  31.  
  32. void    mpthd_setup()
  33. {
  34.     static    MPTHD    mpthd[mpthd_mainmpthds];
  35.     mpthd_me()=    mpthd;
  36.     mpdef_mysize()=    0;
  37.     mpthd_init(mpthd,mpthd_mainmpthds*sizeof(MPTHD),(MPTHDFN)main);
  38.     mpsem_take(str2fld(mpthd_me(),mpsem));
  39. }
  40. /****************************************************************************/
  41. void    mpthd_execute()        /* INTERNAL USE ONLY! */
  42.     /* EXECUTES THE THREAD IN INFINITE mpthdfn / switch LOOP */
  43. {
  44.     MPTHDID    oldmpthd=    mpthd_me()->oldmpthd;    /* SAVE oldmpthd */
  45.  
  46.         /* RELEASE oldmpthd'S SEMAPHORE AND RESTORE INTERRUPTS */
  47.     mpsem_give(&(oldmpthd->mpsem));
  48.     mpsig_state(mpthd_me()->mpsigstate);
  49.  
  50.     /* NEW THREAD INFINITE EVALUATE-SWITCH LOOP */
  51.     for (EVER)
  52.         mpthd_me()->oldmpthd=
  53.             mpthd_switch(
  54.                 (mpthd_me()->mpthdfn)(mpthd_me()->oldmpthd));
  55. }
  56. /****************************************************************************/
  57. MPTHDID    mpthd_init(buff, size, mpthdfn)
  58.     VOIDPTR    buff;
  59.     UINT    size;
  60.     MPTHDFN    mpthdfn;
  61. {
  62.     MPTHDID    mpthd=    (MPTHDID)buff;
  63.     if ((size < (3*sizeof(MPTHD)+mpdef_mysize())))
  64.         return((MPTHDID)0);
  65.     {            /* COPY ALL DEFAULT VALUES OF PARENT THREAD */
  66.         MPDEFID    defpos=    mpdef_size(mpthd)= mpdef_mysize();
  67.         while (defpos--)
  68.             mpthd->mpdefs[defpos]=    mpthd_me()->mpdefs[defpos];
  69.     }
  70.     mpbug_lev();mpbug_valp(mpthd);
  71.  
  72.     /* INITIALIZE "LOCAL" VARIABLES FOR NEW STATE */
  73.     mpthd->mpthdfn=            mpthdfn;
  74.     mpsem_val(&(mpthd->mpsem))=    1;    /* ALLOW AT MOST 1 ACCESSOR */
  75.     mpthd->stackoverflow=        BOOL_FALSE;
  76.  
  77.     /* COPY CURRENT STATE */
  78.     mpthd->mpsigstate=        mpsig_state(MPSIG_ALLBLOCKED);
  79.     if (setjmp(mpthd->state))    mpthd_execute();  /* EXECUTE NEW
  80.                         THREAD WHEN SWITCHED TO */
  81.                     mpsig_state(mpthd->mpsigstate);
  82.  
  83.     /* MODIFY COPY OF CURRENT STATE -- SET UP NEW STACK POINTER */
  84.     {
  85.         UINT    uniqptr=    ptr_2int(buff)
  86.                     + (size-sizeof(mpthd->state));
  87.         char PTR buffend=    int_2ptrh(uniqptr);
  88.         mpbug_vali(size);mpbug_valp(buffend);
  89.         mpbug_bp();
  90. #ifdef    __TURBOC__
  91.         mpbug_lev();mpbug_cmt("Setting stack state");
  92.         mpthd->state[0].j_ss=    FP_SEG(buffend);
  93.         mpthd->state[0].j_sp=    FP_OFF(buffend);
  94. #endif
  95. #ifdef    M_I86
  96.         mpthd->state[3]=    FP_OFF(buffend);
  97.     /*    mpthd->state[?]=    FP_SEG(buffend); */
  98. /* WARNING:    MICROSOFT "C"'s jmp_buf MAY NOT BE POWERFUL ENOUGH TO IMPLEMENT
  99.     CO-ROUTINES (WITH DIFFERENT STACKS) */
  100. #endif
  101. #ifdef    vax
  102.         buffend-=    sizeof(MPTHD);
  103.         mpthd->state[0]=        ptr_2int(buffend);
  104. #endif
  105. #if    (defined(ibm032) || defined(ibm370))
  106.         mpthd->state[0]=        ptr_2int(buffend);
  107. #endif    
  108.     }
  109.     return(mpthd);
  110. }
  111. /****************************************************************************/
  112. VOIDPTR    mpthd_dinit(mpthd)
  113.     MPTHDID    mpthd;
  114. {
  115.  
  116.     if (mpthd==mpthd_me())    return(0);    /* CAN'T DESTROY YOURSELF! */
  117.     mpsem_critsect(str2fld(mpthd,mpsem),{;});/* WAIT UNTIL mpthd IS FREE*/
  118.     return((VOIDPTR)mpthd);
  119. }
  120. /****************************************************************************/
  121. /****************************************************************************/
  122. /* THE mpthd_switch() FUNCTION    - FOR SWITCHING BETWEEN THREADS OF EXECUTION*/
  123. /****************************************************************************/
  124. MPTHDID    mpthd_switch(newmpthd)
  125.     MPTHDID    newmpthd;
  126. {
  127.     mpbug_valp(newmpthd);
  128.     if (newmpthd->stackoverflow)    return((MPTHDID)0);
  129.     if (newmpthd!=mpthd_me()) {
  130.         mpsem_critsect(&(newmpthd->mpsem),{
  131.             if (!setjmp(mpthd_me()->state)) {
  132.                 newmpthd->oldmpthd=    mpthd_me();
  133.                 mpthd_me()=        newmpthd;
  134.                 longjmp(mpthd_me()->state,1);
  135.             }
  136.             newmpthd=    mpthd_me()->oldmpthd;
  137.         });
  138.     }
  139.     return(newmpthd);    /* RETURN OLD THREAD SWITCHED FROM */
  140. }
  141. /****************************************************************************/
  142. /****************************************************************************/
  143.  
  144.