Michael B. Parker, MIT '89 MIT Address: (to 5/19) Home Address: (5/20-6/2) East Campus - Mun. 303 Lucy V. Parker 3 Ames Street 721 E. Walnut Ave. Cambridge, MA 02139 Orange, CA 92667-6833 (617) 225-6303 (714) 639-9497 Jane Tazelaar, Editorial Byte Magazine One Phoenix Mill Lane Peterborough, NH 03458 603-924-9281 Dear Jane, Monday, 16 May 1988 --------- Hope things are going well with you. I called Friday to update you on my progress with the multitasking code and left a message with Ken Sheldon. A few weeks ago you asked me to send you both the final multitasking package (for BIX distribution) and listing of the mpthd_switch() and mpthd_xfer() functions (for printing in BYTE). Right now is finals weeks at MIT. It is the busiest time of the year for me. It is impossible for me to complete the entire package now. However, I have finished the two procedures you requested and sent them to you (see below). In a few days, I will be returning home to California. There, I will finish the package and send it to you by the end of the month. I hope this arrangement will work with your schedule. If it doesn't, please give me a call. Well, either way it works out, I'd enjoy hearing from you again! Thank you for all your support and encouragement. It is an honor to be writing for your magazine. Sincerely, Mike Parker Encl: Code for mpthd_switch() and mptsk_xfer() functions. Tab stops are at every 8th column (standard ASCII). All lines are less than 80 chars. /****************************************************************************/ /* THE mpthd_switch() FUNCTION - FOR SWITCHING BETWEEN THREADS OF EXECUTION*/ /****************************************************************************/ MPTHDID mpthd_switch(newmpthd) MPTHDID newmpthd; { if (newmpthd->stackoverflow) return((MPTHDID)0); if (newmpthd!=mpthd_me()) { mpsem_critsect(&(newmpthd->mpsem),{ if (!setjmp(mpthd_me()->state)) { newmpthd->oldmpthd= mpthd_me(); mpthd_me()= newmpthd; longjmp(mpthd_me()->state,1); } newmpthd= mpthd_me()->oldmpthd; }); } return(newmpthd); /* RETURN OLD THREAD SWITCHED FROM */ } /****************************************************************************/ /****************************************************************************/ /* THE mptsk_xfer() FUNCTION - FOR TRANSFERING MSGS & CTRL BETWEEN TASKS */ /****************************************************************************/ MPMSGID mptsk_xfer(MPBOXID mpbox, MPMSGID mpmsg, BOOL block, MPBOXID sched) { mpsig_critsect(do { /* DISABLE INTERRUPTS */ /*SEND*/ if (mpmsg) { /* IF SENDING A MESSAGE */ MPTSKID mptsk; mptsk= mpbox_xfer(mpbox, /* QUEUE MSG GET TSK */ mptsk_sendside, block?mpmsg:(MPMSGID)0); if (mptsk) { /* A TASK WAS WAITING */ /* TRANSFER MESSAGE */ mptsk_mpmsg(mptsk)= mpmsg; mpmsg= 0; /* SCHEDULE BOTH TASKS */ mpbox_xfer(mptsk_sched(mptsk),mptsk_recvside,mptsk); mpbox_xfer(mptsk_mysched(),mptsk_recvside,mptsk_me()); } else { if (block) mpmsg=0; /* MESSAGE SENT */ break; /* RETURN IMMEDIATELY */ } /*RECV*/} else { /* IF RECEIVING A MESSAGE */ mpmsg= mpbox_xfer(mpbox, /* GET MSG QUEUE TSK */ mptsk_recvside, block?mptsk_me():(MPMSGID)0); if (mpmsg) break; /* MESSAGE RECVED: RET IMMEDIATELY */ if (!block) break; /* DON'T WAIT FOR MSG: RET IMMDLY */ } /*SCHD*/{ /* SCHEDULE A NEW TASK TO RUN */ MPTSKID mptsk; MPBOXID cursched= sched; /* USE USER SCHED LIST */ /* SEARCH FROM HIGHEST TO LOWEST PRIORITY 'TILL TASK FOUND */ while (!(mptsk= mpbox_xfer(cursched,mptsk_recvside, (MPMSGID)0))){ cursched= mprng_next(cursched); if (cursched==sched) /* IF END OF USER SCHED LIST*/ cursched= mptsk_topsched(); /* USE SYS LST */ } mptsk_mympmsg()=mpmsg; /* SAVE MESSAGE BETWEEN SWITCHES */ mpthd_switch(str2fld(mptsk,mpthd)); mpmsg= mptsk_mympmsg();/* RETURN RESULT MESSAGE */ } } while (0);); return(mpmsg); } /****************************************************************************/ /****************************************************************************/ /* MACROS FOR TYPICAL USES OF THE mptsk_xfer() FUNCTION */ /****************************************************************************/ #define mptsk_send(mpbox,mpmsg) /* SEND mpmsg TO mpbox */ \ mptsk_xfer(mpbox,mpmsg,BOOL_TRUE,mptsk_topsched()) #define mptsk_csend(mpbox,mpmsg)/* SEND mpmsg TO mpbox IFF HAS A RECVR */ \ mptsk_xfer(mpbox,mpmsg,BOOL_FALSE,mptsk_topsched()) #define mptsk_recv(mpbox) /* RECV A MPMSG FROM mpbox */ \ mptsk_xfer(mpbox,(MPMSGID)0,BOOL_TRUE,mptsk_topsched()) #define mptsk_crecv(mpbox) /* RECV A MPMSG FROM mpbox IFF HAS A MSG */ \ mptsk_xfer(mpbox,(MPMSGID)0,BOOL_FALSE,mptsk_topsched()) #define mptsk_yield() /* TEMPORARILY YIELD CTRL TO OTHER TASKS */ \ mptsk_recv(mpbox_mysched()) #define mptsk_yieldto(sched) /* TEMPORARILY YIELD CTRL TO sched TSK LST */\ mptsk_xfer(mpbox_mysched(),(MPMSGID)0,BOOL_TRUE,sched) /****************************************************************************/