home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************/
- /* mpres.c -- MAIL BOX MULTITASKING CLUSTER (IMPLEMENTATION) */
- /* Created: 06/26/88 Release: 0.7 Version: 06/27/88 */
- /****************************************************************************
- (c) Copyright 1987, 1988 by Michael Benjamin Parker (USA SS# 557-49-4130)
-
- All Rights Reserved unless specified in the following include files: */
- #include "mptsk.cpy" /*
-
- DO NOT REMOVE OR ALTER THIS NOTICE AND ITS PROVISIONS.
- ****************************************************************************/
- /* OVERVIEW: See mpres.h */
-
- WARNING WARNING: This code has not been debugged. It is
- presented only for educational purposes and will likely not work. It
- will be completed by release 1.0.
-
-
- NOTES ON CONSTRUCTING HANDLERS FOR HARDWARE INTERRUPTS:
-
- Hardware interrupts (interrupts on a processor not explicitly invoked
- by the processor) must be handled very carefully. The purpose of the
- hardware interrupt handler is to merely *indicate* to the scheduler
- that an interrupt has occured. By comparing the current task's
- priority with that of the task waiting for the interrupt, the
- scheduler may then decide whether to process the interrupt now or
- hold off until some time later. The handler should NOT process the
- interrupt, as this may require system resources and CPU time. It
- should only indicate that the interrupt has occured.
-
- Here are some rules for constructing safe hardware interrupt handlers:
-
- The handler must not access any system (global) resources,
- including dynamic heap memory allocation/deallocation.
-
- The handler may allocate a small amount of temporary stack memory
- for handling the current interrupt.
-
- The handler may also access shared static memory, however,
- accesses to this memory must be autonomous. Whenever this memory is
- accessed, the accessing processor must block all interrupts which
- may access the memory, then, by claiming a semaphore on the memory, attempt
- to block all processors which may access that memory; if the claim fails,
- interrupts should be restored to their prior state before trying
- again. Because autonomous accesses are exclusive, they must be very fast.
-
- The handler must execute VERY quickly (in negligable time).
-
- In general, it is probably simplest and safest to disable all
- interrupts within a hardware interrupt handler.
-
-
- /****************************************************************************/
- /****************************************************************************/
- #include "mpmisc.h"
- #include "mpres.h"
- #include "mptsk.h"
- #include <errno.h>
- #ifdef __MSDOS__
- #include "mpdos.h"
- #endif
- #ifdef unix
- #include <signal.h>
- #include <fcntl.h>
- #include <sys/ioctl.h>
- #endif
- /****************************************************************************/
- /****************************************************************************/
- /****************************************************************************/
- typedef MPBOX MPRES, MPRES, PTR MPRESID;
- typedef struct _MPSOR MPSOR, PTR MPSORID;
-
- struct _MPSOR {
- MPMSG mpmsg; /* MESSAGE HEADER */
- MPTSKID mptsk; /* TASK WHICH OWNS THE RESOURCE */
- MPRESID mpres; /* RESOURCE OF WHICH THIS IS A SOURCE */
-
- }
- /****************************************************************************/
- /****************************************************************************/
-
- MPRES mpres_stdin[1],mpres_stdout[1],mpres_stderr[1];
- MPRES mpres_filesystem[1],mpres_network[1],mpres_terminalin[1],mpres_terminalout[1];
- MPRES mpres_harddisk[1],mpres_floppydisk[1],mpres_modem[1],mpres_printer[1],
- mpres_parallel[1],mpres_serial[1];
- /****************************************************************************/
- /****************************************************************************/
- /****************************************************************************/
- /* mpres / mpbox FUNCTION CALLS */
- #define mpres_init mpbox_init
- #define mpscd_init mpbox_init
- #define mpres_dinit mpbox_dinit
- #define mpscd_dinit mpbox_dinit
- #define mpres_create mpbox_create
- #define mpscd_create mpbox_create
- #define mpres_destroy mpbox_destroy
- #define mpscd_destroy mpbox_destroy
- /****************************************************************************/
- MPBOXID mpbox_create(void)
- {
- MPBOXID mpbox;
- mpres_ram(mpbox= (MPBOXID)malloc(sizeof(MPBOX)));
- if (mpbox) mpbox_init(mpbox);
- return(mpbox);
- }
- /****************************************************************************/
- void mpbox_destroy(MPBOXID mpbox)
- {
- mpbox_dinit(mpbox);
- mpres_ram(free(mpbox));
- }
- /****************************************************************************/
- /****************************************************************************/
- /* mpsor FUNCTION CALLS */
- MPSORID mpsor_init(VOIDPTR buf,MPRESID mpres)
- {
- MPSORID mpsor= (MPSORID)buf;
- mprng_init(str2fld(mpsor,mpmsg));
- mpsor->mptsk= 0;
- mpsor->mpres= mpres;
- return(mpsor);
- }
- MPSORID mpsor_create(MPRESID mpres)
- {
- MPSORID mpsor;
- mpres_ram(mpsor= (MPSORID)malloc(sizeof(MPSOR)));
- if (mpsor) mpsor_init(mpsor,mpres);
- return(mpsor);
- }
- /****************************************************************************/
- VOIDPTR mpsor_dinit(MPSORID mpsor)
- {
- mprng_dinit(str2fld(mpsor,mpmsg);
- return((VOIDPTR)mpsor);
- }
- /****************************************************************************/
- void mpsor_destroy(MPSORID mpsor)
- {
- mpsor_dinit(mpsor);
- mpres_ram(free(mpsor));
- }
- /****************************************************************************/
- /****************************************************************************/
- /* mpres/mpsor COMBINATION FUNCTION CALLS */
- /****************************************************************************/
- MPSORID mpres_mpsor(MPRESID mpres,MPTSKID mptsk)
- {
- MPSORID mpsor= mptsk_owns(mptsk);
- while ((mpsor= mprng_next(mpsor)) != mptsk_owns(mptsk))
- if (mpsor->mpres == mpres) return(mpsor);
- return(0);
- }
- #define mpres_mympsor(mpres) mpres_mpsor(mpres,mptsk_me())
- /****************************************************************************/
- #define mpres_takenew(mpres) mptsk_recv(mpres)
- #define mpres_giveold(mpsor) mptsk_send((mpsor)->mpres,mpsor)
- /****************************************************************************/
- /****************************************************************************/
- void mpres_take(mpres)
- {
- MPSORID mpsor= mpres_mympsor(mpres);
- if (!mpsor) {
- mpsor= mpres_takenew(mpres);
- mprng_twistnn(mpsor,mptsk_myowns());
- }
- }
- /****************************************************************************/
- void mpres_give(mpres)
- {
- MPSORID mpsor= mpres_mympsor(mpres);
- if (mpsor) {
- mprng_sub(mpsor);
- mpres_giveold(mpsor);
- }
- }
-
- /****************************************************************************/
- /****************************************************************************/
- #define mpres_critsect(mpres,CODEBLOCK) \
- { \
- mpres_take(mpres); \
- {CODEBLOCK}; \
- mpres_give(mpres); \
- }
- /****************************************************************************/
- /****************************************************************************/
-
-
-
- /****************************************************************************/
- /* RAM CONTENTION MANAGEMENT */
- MPRES _mpres_ram[1];
- MPSOR _mpsor_ram[1];
- #define mpres_ram(RAMCALLS) mpres_critsect(_mpres_ram,RAMCALLS)
- /****************************************************************************/
- /* errno CONTENTION MANAGEMENT */
- MPRES _mpres_errno[1];
- MPSOR _mpsor_errno[1];
- #define mpres_errno(IOCALLS) mpres_critsect(_mpres_errno,IOCALLS)
- /****************************************************************************/
- /****************************************************************************/
- /****************************************************************************/
- /* PRE-EMPTIVE MULTIPROCESSING */
- /****************************************************************************/
- #define MPSIG_CLOCKTICK (0x08)
- void (* _mpsig_oldclocktick)();
- void _mpsig_clocktick()
- {
- #ifdef __MSDOS__
- _mpsig_oldclocktick();
- #endif
- #ifdef unix
- alarm(1); /* CALL ME AGAIN IN 1 SECOND */
- #endif
- mptsk_yield();
- }
- /****************************************************************************/
- MPTHDID _mpthdfn_idletask(MPTHDID mpthd)
- {
- for(ever) mptsk_yield();
- }
- /****************************************************************************/
- MPTHDID mpthdfn_death(MPTHDID mpthd)
- {
- for(ever)
- mpthd_destroy(mptsk_destroy(mptsk_recv(mptsk_mympbox())));
- }
- /****************************************************************************/
- /****************************************************************************/
- /****************************************************************************/
- /* INTERRUPT OPTIMIZATIONS -- MS-DOS */
- #ifdef __MSDOS__
- /****************************************************************************/
- /****************************************************************************/
- #define MPSIG_KEYSTROKE (0x09)
- MPRES _mpres_keyboard[1];
- void interrupt (* _mpsig_oldkeystroke)(void);
- void interrupt _mpsig_keystroke(void)
- {
- _mpsig_oldkeystroke();
- mptsk_broadcast(mpres_keystroke,(MPMSGID)~0);
- }
- /****************************************************************************/
- #define MPSIG_KEYBOARD (0x16)
- void interrupt (* _mpsig_oldkeyboard)();
- void interrupt _mpsig_keyboard(bp, di, si, ds, es, dx, cx, bx,
- char al, char ah, ip, cs, flags)
- {
- if (ah==0) { /* IF ABOUT TO READ A CHARACTER */
- /* WHILE NO CHARACTER IS AVAILABLE */
- while(_AH= 1, _mpsig_oldkeystroke(), flags & FLAG_ZF)
- /* WAIT TO BE SIGNALED */
- mptsk_recv(_mpres_keyboard);
- }
- _AH= ah;
- _mpsig_oldkeystroke();
- }
- #endif /* __MSDOS__ */
- /****************************************************************************/
- /****************************************************************************/
- /****************************************************************************/
- /* INTERRUPT OPTIMIZATIONS -- UNIX */
- #ifdef unix
- /****************************************************************************/
- /****************************************************************************/
- MPRES _mpres_io[1];
- void (* _mpsig_oldsigio)();
-
- void _mpsig_sigio(void)
- {
- _mpsig_oldsigio();
- mptsk_broadcast(mpres_io,(MPMSGID)~0);
- }
- #define mpres_io(IOCALL) \
- for(ever) { \
- int _errno; \
- mpres_critsect(mpres_errno, { \
- errno= 0; \
- {IOCMD}; \
- _errno= errno; \
- }); \
- if (_errno!=EWOULDBLOCK) break; \
- mptsk_recv(_mpres_io); \
- }
-
- #define mpres_ioinit(filedescriptor) \
- fcntl(filedescriptor,F_SETFL, \
- fcntl(filedescriptor,F_GETFL) | FNDELAY | FASYNC)
-
- #endif /* unix */
- /****************************************************************************/
- /****************************************************************************/
- void mpres_setup(void)
- {
- mpres_init(_mpres_ram);
- mpres_init(_mpres_errno);
- mptsk_create(mpthd_create(mpthdfn_death,1000),mpscd_toptasks());
- mptsk_create(mpthd_create(mpthdfn_idletask,1000),mpscd_idletasks);
-
- #ifdef __MSDOS__
- _mpsig_oldclocktick= mpdos_vect(MPSIG_CLOCKTICK,_mpsig_clocktick);
- _mpsig_oldkeystroke= mpdos_vect(MPSIG_KEYSTROKE,_mpsig_keystroke);
- _mpsig_oldkeyboard= mpdos_vect(MPSIG_KEYBOARD, _mpsig_keyboard);
- #endif
- #ifdef unix
- _mpsig_oldclocktick= signal(SIGALRM,_mpsig_clocktick);
- _mpsig_oldsigio= signal(SIGIO,_mpsig_sigio);
- #endif
- }
- /****************************************************************************/
- /****************************************************************************/
- /****************************************************************************/
- MPTHDID mpthd_create(MPTHDFN mpthdfn,UINT threadsize)
- {
- MPTHDID mpthd;
- mpres_ram(mpthd= (MPTHDID)malloc(3*sizeof(MPTHD)+threadsize));
- if (mpthd) mpthd= mpthd_init(mpthd,3*sizeof(MPTHD)+threadsize));
- return(mpthd);
- }
- void mpthd_destroy(MPTHD mpthd)
- {
- if (mpthd) mpres_ram(free(mpthd_dinit(mpthd)));
- }
- /****************************************************************************/
- MPTSKID mptsk_create(MPTHD mpthd, MPSCDID sched)
- {
- MPTSKID mptsk;
- mpres_ram(mptsk= (MPTSKID)malloc(sizeof(MPTSK)));
- if (mpthd && mptsk) mptsk= mptsk_init(mptsk,mpthd,sched);
- return(mptsk);
- }
- MPTHDID mptsk_destroy(MPTSKID mptsk)
- {
- MPTHDID mpthd= 0;
- if (mptsk) {
- mpthd= mptsk_mpthd(mptsk);
- mpres_ram(free(mptsk_dinit(mptsk));
- }
- return(mpthd);
- }
- /****************************************************************************/
- /****************************************************************************/