|
|
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.