|
|
1.1 ! root 1: /* ! 2: * This example illustrates the use of shared memory and ram semaphores ! 3: * between separate processes. One process reads and stores keystrokes ! 4: * into a circular buffer in shared memory, and another reads the buffer ! 5: * and writes to standard output. The output program throttles output to ! 6: * one character per sec so the effect of buffering can be seen. Type ! 7: * CONTROL-d to terminate. ! 8: * ! 9: * Note the mutual exclusion on access to the head and tail pointers of the ! 10: * buffer. For a discussion, see Peterson & Silberschatz, "Operating ! 11: * System Concepts", 2nd ed., chapter 9. ! 12: * ! 13: * Be aware when running this that the system does keyboard buffering ! 14: * underneath this program, so you can type ahead more than you might think. ! 15: * ! 16: * Needs shrchild.c as companion program. ! 17: * ! 18: * Compile as: cl -AL -G2 -Lp share.c ! 19: * ! 20: * Copyright (C) Microsoft Corp. 1986 ! 21: */ ! 22: ! 23: #include <doscalls.h> ! 24: #include <subcalls.h> ! 25: #include "share.h" /* common declarations between processes */ ! 26: ! 27: #define CHILD1PROG "SHRCHILD.EXE" /* child process */ ! 28: #define CTRLd 4 /* termination character */ ! 29: #define FBSZ 32 ! 30: ! 31: struct KeyData KeyData; /* declared in subcalls.h */ ! 32: ! 33: main() ! 34: { ! 35: unsigned Selector; ! 36: struct ResultCodes childID; /* child process id */ ! 37: unsigned nBytes; ! 38: unsigned rc; /* return code */ ! 39: char c, ! 40: fbuf[FBSZ]; /* failing object buffer */ ! 41: struct ShareRec *SmemPtr; /* shared memory pointer */ ! 42: ! 43: /* allocate the shared memory segment */ ! 44: if (rc = DOSALLOCSHRSEG( SHRSEGSIZE, (char *)SHRSEGNAME, ! 45: (unsigned *)&Selector )) { ! 46: printf("alloc of shared memory failed, error: %d\n", rc); ! 47: DOSEXIT(1, 0); ! 48: } ! 49: ! 50: /* Get a far pointer from a 16 bit selector */ ! 51: SmemPtr = (struct ShareRec *) GETSEGPTR(Selector, 0); ! 52: ! 53: /* Initialize circular buffer flags */ ! 54: DOSSEMCLEAR((long)&(SmemPtr->fullsem)); ! 55: DOSSEMSET((long)&(SmemPtr->emptysem)); ! 56: DOSSEMCLEAR((long)&(SmemPtr->mutexsem)); ! 57: SmemPtr->head = 0; ! 58: SmemPtr->tail = 0; ! 59: ! 60: /* exec asynchronously the consumer process */ ! 61: if (rc = DOSEXECPGM( ! 62: (char *) fbuf, /* ObjNameBuf */ ! 63: (unsigned) FBSZ, /* ObjNameLen */ ! 64: (unsigned) 1, /* AsyncTraceFlags */ ! 65: (char *) 0L, /* Argument Strings */ ! 66: (char *) 0L, /* Environment Strings */ ! 67: (struct ResultCodes *) &childID, ! 68: /* ID & Termination Codes */ ! 69: (char *) CHILD1PROG )) { /* Program Filename */ ! 70: ! 71: printf("exec of child process failed, error: %d\n", rc); ! 72: DOSEXIT(1, 0); ! 73: } ! 74: ! 75: /* Here, we read chars from the keyboard, and put them in a */ ! 76: /* circular buffer in shared memory */ ! 77: ! 78: KBDCHARIN(&KeyData, 0, 0); /* read character from keyboard */ ! 79: ! 80: while((c = KeyData.char_code) != CTRLd) { ! 81: ! 82: /* block if buffer full */ ! 83: DOSSEMWAIT((long)&(SmemPtr->fullsem), WAITFOREVER); ! 84: ! 85: /* mutual exclusion on buffer pointers */ ! 86: DOSSEMREQUEST((long)&(SmemPtr->mutexsem), WAITFOREVER); ! 87: SmemPtr->CircBuffer[SmemPtr->head] = c; ! 88: SmemPtr->head++; /* step pointer */ ! 89: SmemPtr->head %= CIRCBUFSIZE; /* wrap at end */ ! 90: if(BUFFUL(SmemPtr)) /* set semaphore if buffer full */ ! 91: DOSSEMSET((long)&(SmemPtr->fullsem)); ! 92: DOSSEMCLEAR((long)&(SmemPtr->mutexsem)); ! 93: ! 94: DOSSEMCLEAR((long)&(SmemPtr->emptysem)); /* indicate buf !emtpy */ ! 95: ! 96: KBDCHARIN(&KeyData, 0, 0); /* read character from keyboard */ ! 97: } ! 98: DOSKILLPROCESS( 1, childID.TermCode_PID ); /* kill consumer */ ! 99: DOSEXIT( 1, 0 ); /* exit, terminating all threads */ ! 100: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.