|
|
1.1 root 1: /*
2: * argument.c
3: *
4: * This program demonstrated a method of passing parameters to a thread.
5: * Since Intel stacks grow down (High to low memory), and the PUSH instruction
6: * decrements the pointer BEFORE writing to the stack, we do the same in C.
7: *
8: * The decrement before writing is important since the line:
9: *
10: * threadStack += STACK_SIZE
11: *
12: * will place the pointer one element BEYOND the end of the stack.
13: *
14: * Also note that the stack is defined as a WORD array. This is so the
15: * decrement operator will adjust the stack by 2 with each push.
16: *
17: * One last caveat: what the thread expects upon the stack depends upon
18: * how each argument is declared and the model that the program is being
19: * compiled in. KNOW YOUR C STACK STRUCTURE!
20: *
21: * Many of the C runtime library routines, including printf, are not
22: * re-entrant. DOSENTERCRITSEC & DOSEXITCRITSEC guarantee serial access
23: * to the screen.
24: *
25: */
26: #include <doscalls.h>
27: #include <stdio.h>
28:
29: #define STACK_SIZE 256 /* stack size in WORDS (see malloc) */
30:
31: main(ac, av)
32: char *av[];
33: int ac;
34: {
35: void far thread(); /* address where thread gets control */
36: int far *threadStack; /* far pointer to thread stack (word)*/
37: unsigned threadID; /* thread ID */
38: unsigned rc; /* return code */
39:
40: /* allocate stack space for thread */
41: /* since this is written in C, DOSALLOCSEG cannot be used here */
42:
43: if ((threadStack = (int *)malloc(sizeof(int) * STACK_SIZE)) == NULL) {
44: printf("thread stack malloc failed\n");
45: DOSEXIT(1, 1); /* terminate all threads and return error */
46: }
47: threadStack += STACK_SIZE; /* since stack grows down */
48:
49: *--threadStack = 0xFFFF; /* Arg #5 = FFFF */
50: *--threadStack = 0xEEEE; /* Arg #4 ... */
51: *--threadStack = 0xDDDD; /* Arg #3 */
52: *--threadStack = 0xCCCC;
53: *--threadStack = 0xBBBB;
54:
55: if (rc = DOSCREATETHREAD(thread, (unsigned far *)&threadID,
56: (char far *)threadStack)) {
57: printf("create of thread failed, error: %d\n", rc);
58: DOSEXIT(1, 1);
59: }
60: DOSENTERCRITSEC();
61: printf("Thread ID = %d\n", threadID);
62: DOSEXITCRITSEC();
63:
64: DOSEXIT(0, 0); /* Terminate, Let the other thread run */
65: }
66:
67:
68: /*
69: * Thread process expects 5 arguments on the stack (normal C calling
70: * convention).
71: */
72: void far
73: thread(a1,a2,a3,a4,a5)
74: int a1,a2,a3,a4,a5;
75: {
76: DOSENTERCRITSEC();
77: printf("Argument 1 = %x\n", a1);
78: DOSEXITCRITSEC();
79:
80: DOSENTERCRITSEC();
81: printf("Argument 2 = %x\n", a2);
82: DOSEXITCRITSEC();
83:
84: DOSENTERCRITSEC();
85: printf("Argument 3 = %x\n", a3);
86: DOSEXITCRITSEC();
87:
88: DOSENTERCRITSEC();
89: printf("Argument 4 = %x\n", a4);
90: DOSEXITCRITSEC();
91:
92: DOSENTERCRITSEC();
93: printf("Argument 5 = %x\n", a5);
94: DOSEXITCRITSEC();
95:
96: DOSEXIT(0,0);
97: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.