fork download
  1. /* -------------------------- loader.c ----------------------- */
  2. /* This is the shell for developing the loader cpu and printer */
  3. /* for csc 389 project */
  4.  
  5. #include <stdio.h>
  6. #include <errno.h>
  7. #include <fcntl.h>
  8. #include<sys/types.h>
  9. #include<sys/ipc.h>
  10. #include<sys/sem.h>
  11. #include<sys/shm.h>
  12.  
  13. #define SLEEP_INC 1
  14. #define BADADDR (char *)(-1) /* used in getting shared memeory */
  15. #define NUM_OF_SEMS 8 /* the number of sems to create */
  16. #define OK_TO_LOAD0 0
  17. #define OK_TO_LOAD1 1
  18. #define OK_TO_EXEC0 2
  19. #define OK_TO_EXEC1 3
  20. #define OK_TO_SET_OUTPUT0 4
  21. #define OK_TO_SET_OUTPUT1 5
  22. #define OK_TO_PRINT0 6
  23. #define OK_TO_PRINT1 7
  24. #define HOWMANY_PROCESSES 3
  25. #define HOWMANY_JOBS 2
  26. #define MALLOC(x) ((x *) malloc(sizeof(x)))
  27. #define CLR system("clear")
  28. #define TRUE 1
  29. #define FALSE 0
  30.  
  31. int my_semid, my_shrmemid; /* semaphore id and shared memory ids */
  32. int my_key; /* key used to get shared memory */
  33. int my_semval;
  34. char *my_shrmemaddr; /* address of shared memory */
  35. typedef struct _pcb
  36. { int start_loc, num_instructions, output_loc;}
  37. pcb_type;
  38. typedef struct _mem
  39. { char operation; int operand1, operand2, result;}
  40. memory_type;
  41. int * load_job, *print_job;
  42. pcb_type *pcbs;
  43. memory_type *memory;
  44. int size_of_memory;
  45. int s, i;
  46.  
  47. char input[100]; /* print to file or print to screen */
  48. char str1[100];
  49. char str2[100];
  50. FILE *f = fopen("cpu.output", "w");
  51.  
  52. /* functions to be invoked later */
  53. void V(); /*release semaphore */
  54. static void semcall(); /* call semop */
  55. void P(); /* acquire semaphore */
  56. void init_sem(); /* initialize semaphores */
  57. void syserr(); /* print error messages */
  58. void remove_shrmem(); /* remove shared memory */
  59. void remove_sem(); /* remove semaphores */
  60. void driver(); /* driver for forking processes */
  61. void loader();
  62. void cpu();
  63. void printer();
  64. int fill_memory();
  65. void execute_memory();
  66. void print_memory();
  67.  
  68. main ()
  69. { /* main program */
  70. /* this program uses semaphores and shared memory. Semaphores are
  71.   used to protect the shared memory which serves as a message area
  72.   for and sender and receiver process */
  73.  
  74.  
  75. printf("Do you want to print the output to screen or file: \n"); /* Ask if the user wants to print to screen or file */
  76. fgets(input, 100, stdin); /* Take user input and store it in variable input */
  77.  
  78. int i ;
  79.  
  80. setbuf(stdout, NULL);
  81. /* get semaphore id and a given number of semaphores */
  82. if ((my_semid = semtran(NUM_OF_SEMS)) != -1)
  83. {
  84. /* initialize the semaphores */
  85. init_sem(my_semid, OK_TO_LOAD0, 1);
  86. init_sem(my_semid,OK_TO_LOAD1, 1);
  87. init_sem(my_semid,OK_TO_EXEC0, 0);
  88. init_sem(my_semid,OK_TO_EXEC1, 0);
  89. init_sem(my_semid,OK_TO_SET_OUTPUT0, 1);
  90. init_sem(my_semid,OK_TO_SET_OUTPUT1, 1);
  91. init_sem(my_semid,OK_TO_PRINT0, 0);
  92. init_sem(my_semid,OK_TO_PRINT1, 0);
  93. }
  94. /* get shared memory segement id and attach it to my_shrmemaddr */
  95. size_of_memory = 2*sizeof(*load_job) + 2*sizeof(*print_job) +
  96. 4*sizeof(*pcbs) + 40 * sizeof(*memory);
  97. if ((get_attach_shrmem(size_of_memory,&my_shrmemaddr,
  98. &my_shrmemid)) != -1)
  99. /* connect to shared memory at my_shrmemaddr */
  100. load_job = (int *) my_shrmemaddr;
  101. print_job = load_job + 2;
  102. pcbs = (pcb_type *) (print_job + 2);
  103. memory = (memory_type *) (pcbs + 4);
  104. /* call driver to do the work of forking senders and receivers */
  105. driver();
  106. /* wait until all processes have completed their work */
  107. for (i = 1; i <= HOWMANY_PROCESSES; i++) wait(&s);
  108. printf("ending \n");
  109. /* remove the semaphores */
  110. remove_sem(my_semid);
  111. /* remove the shared memory */
  112. remove_shrmem(my_shrmemid, my_shrmemaddr);
  113. exit(0);
  114.  
  115. fclose(f);
  116. } /* end of main */
  117.  
  118. void driver() /* driver to fork processes for readers and writers*/
  119. {
  120. int pid;
  121.  
  122. /* fork processes to handle the work */
  123. if (( pid = fork() ) == -1) syserr("fork");
  124. if ( pid == 0 )
  125. {
  126. loader();
  127. /* called printer just to test if loader
  128.   was loading the shared memory */
  129. exit(0);
  130. }
  131. if (( pid = fork() ) == -1) syserr("fork");
  132. if ( pid == 0 )
  133. {
  134. cpu();
  135. exit(0);
  136. }
  137. if (( pid = fork() ) == -1) syserr("fork");
  138. if ( pid == 0 )
  139. {
  140. printer();
  141. exit(0);
  142. }
  143. } /* end of driver */
  144.  
  145. void loader()
  146. {
  147. FILE *fid;
  148. int memory_to_load, current_job;
  149. int more_jobs;
  150. int job_read;
  151.  
  152. if ((fid = fopen ("cpu.dat", "r")) == 0)
  153. {
  154. puts ("Unable to open file for reading.");
  155. return;
  156. }
  157. more_jobs = 2;
  158. current_job = 0;
  159. while (more_jobs)
  160. {
  161. if (current_job == 0)
  162. {
  163. P(my_semid, OK_TO_LOAD0);
  164. memory_to_load = 0;
  165. pcbs[current_job].start_loc = 0;
  166. pcbs[current_job].output_loc = 20;
  167. pcbs[current_job].num_instructions = 0;
  168. job_read = fill_memory(fid, memory_to_load);
  169. if (job_read != 4)
  170. {
  171. more_jobs = more_jobs - 1;
  172. load_job[current_job] = -1;
  173. }
  174. else
  175. load_job[current_job] = 1;
  176. V(my_semid, OK_TO_EXEC0);
  177. }
  178. else
  179. {
  180. P(my_semid, OK_TO_LOAD1);
  181. memory_to_load = 10;
  182. pcbs[current_job].start_loc = 10;
  183. pcbs[current_job].output_loc = 30;
  184. pcbs[current_job].num_instructions = 0;
  185. job_read = fill_memory(fid, memory_to_load);
  186. if (job_read != 4)
  187. {
  188. more_jobs = more_jobs - 1;
  189. load_job[current_job] = -1;
  190. }
  191. else
  192. load_job[current_job] = 1;
  193. V(my_semid, OK_TO_EXEC1);
  194. }
  195. current_job = (current_job + 1) % 2;
  196. } /* end while more_jobs */
  197. /* failed to read the four items */
  198. fclose(fid);
  199. return;
  200. } /* end of load */
  201.  
  202. int fill_memory (fid, memory_to_fill)
  203. FILE *fid;
  204. int memory_to_fill;
  205. {
  206. int opcode_ok, end_of_job, bad_instruction;
  207. char opcode, cr;
  208. int operand1, operand2;
  209. int elements_read, current_pcb ;
  210.  
  211. if (memory_to_fill == 0)
  212. current_pcb = 0;
  213. else
  214. current_pcb = 1;
  215. elements_read = TRUE;
  216. end_of_job = FALSE;
  217. while (elements_read )
  218. {
  219. elements_read = fscanf (fid, "%c %d %d%c", &opcode, &operand1,
  220. &operand2,&cr);
  221. if (elements_read != 4)
  222. {
  223. return(elements_read);
  224. }
  225. else
  226. {
  227. switch (opcode)
  228. {
  229. case '+':
  230. opcode_ok = TRUE;
  231. break;
  232. case '-':
  233. opcode_ok = TRUE;
  234. break;
  235. case '*':
  236. opcode_ok = TRUE;
  237. break;
  238. case '/':
  239. opcode_ok = TRUE;
  240. break;
  241. case '%':
  242. opcode_ok = TRUE;
  243. break;
  244. default :
  245. if (opcode == '?')
  246. {
  247. bad_instruction = FALSE;
  248. end_of_job = TRUE;
  249. }
  250. else
  251. {
  252. end_of_job = FALSE;
  253. opcode_ok = FALSE;
  254. bad_instruction = TRUE;
  255. };
  256. } /* end of switch */
  257. } /* end of else elements read was 4 */
  258. if (end_of_job == TRUE)
  259. return( elements_read);
  260. pcbs[current_pcb].num_instructions =
  261. pcbs[current_pcb].num_instructions + 1;
  262. memory[memory_to_fill].operation = opcode;
  263. memory[memory_to_fill].operand1 = operand1;
  264. memory[memory_to_fill].operand2 = operand2;
  265. memory_to_fill = memory_to_fill + 1;
  266. } /* end of while for fill memory */
  267. } /* end of fill memory */
  268.  
  269. void cpu()
  270. {
  271. int memory_to_execute, current_job;
  272. int where_to_output, memory_to_output;
  273. int more_jobs;
  274.  
  275. current_job = 0;
  276. more_jobs = 2;
  277. while (more_jobs)
  278. {
  279. if (current_job == 0)
  280. {
  281. P(my_semid, OK_TO_EXEC0);
  282. if (load_job[current_job] == -1)
  283. {
  284. more_jobs = more_jobs -1;
  285. P(my_semid, OK_TO_SET_OUTPUT0);
  286. print_job[current_job] = -1;
  287. V(my_semid, OK_TO_LOAD0);
  288. V(my_semid, OK_TO_PRINT0);
  289. }
  290. else
  291. {
  292. execute_memory(current_job);
  293. P(my_semid, OK_TO_SET_OUTPUT0);
  294. pcbs[current_job + 2] = pcbs[current_job];
  295. memory_to_output = pcbs[current_job + 2].start_loc;
  296. where_to_output = pcbs[current_job + 2].output_loc;
  297. for (i = 1; i <= pcbs[current_job + 2].num_instructions; i++)
  298. {
  299. memory[where_to_output] = memory[memory_to_output];
  300. memory_to_output = memory_to_output + 1;
  301. where_to_output = where_to_output + 1;
  302. }
  303. load_job[current_job] = 0;
  304. print_job[current_job] = 1;
  305. V(my_semid, OK_TO_LOAD0);
  306. V(my_semid, OK_TO_PRINT0);
  307. } /* end for else for load job[current_job] != -1 */
  308. }
  309. else /* job is number 1 */
  310. {
  311. P(my_semid, OK_TO_EXEC1);
  312. if (load_job[current_job] == -1)
  313. {
  314. more_jobs = more_jobs -1;
  315. P(my_semid, OK_TO_SET_OUTPUT1);
  316. print_job[current_job] = -1;
  317. V(my_semid, OK_TO_LOAD1);
  318. V(my_semid, OK_TO_PRINT1);
  319. }
  320. else
  321. {
  322. execute_memory(current_job);
  323. P(my_semid, OK_TO_SET_OUTPUT1);
  324. pcbs[current_job + 2] = pcbs[1];
  325. memory_to_output = pcbs[current_job + 2].start_loc;
  326. where_to_output = pcbs[current_job + 2].output_loc;
  327. for (i = 1; i <= pcbs[current_job + 2].num_instructions; i++)
  328. {
  329. memory[where_to_output] = memory[memory_to_output];
  330. memory_to_output = memory_to_output + 1;
  331. where_to_output = where_to_output + 1;
  332. }
  333. load_job[current_job] = 0;
  334. print_job[current_job] = 1;
  335. V(my_semid, OK_TO_LOAD1);
  336. V(my_semid, OK_TO_PRINT1);
  337. } /* end for else for load job[1] != -1 */
  338. }
  339. current_job = (current_job + 1) % HOWMANY_JOBS;
  340. } /* end while more jobs */
  341. } /* end of cpu */
  342.  
  343. void execute_memory(current_job)
  344. int current_job;
  345. {
  346. int memory_to_execute;
  347. int i;
  348.  
  349. if (current_job == 0)
  350. memory_to_execute = 0;
  351. else
  352. memory_to_execute =10;
  353. for ( i = 1; i <= pcbs[current_job].num_instructions; i++)
  354. {
  355. switch (memory[memory_to_execute].operation)
  356. {
  357. case '+':
  358. memory[memory_to_execute].result =
  359. memory[memory_to_execute].operand1 +
  360. memory[memory_to_execute].operand2 ;
  361. break;
  362. case '-':
  363. memory[memory_to_execute].result =
  364. memory[memory_to_execute].operand1 -
  365. memory[memory_to_execute].operand2 ;
  366. break;
  367. case '*':
  368. memory[memory_to_execute].result =
  369. memory[memory_to_execute].operand1 *
  370. memory[memory_to_execute].operand2 ;
  371. break;
  372. case '/':
  373. memory[memory_to_execute].result =
  374. memory[memory_to_execute].operand1 /
  375. memory[memory_to_execute].operand2 ;
  376. break;
  377. case '%':
  378. memory[memory_to_execute].result =
  379. memory[memory_to_execute].operand1 %
  380. memory[memory_to_execute].operand2 ;
  381. break;
  382. } /* end of switch */
  383. memory_to_execute = memory_to_execute + 1;
  384. }
  385. } /* end execute_memory */
  386.  
  387. void printer()
  388. {
  389. /* print jobs */
  390. /* the code below was added to test if the loader was filling
  391.   memory */
  392. int memory_to_print;
  393. int current_print_job;
  394. int more_print_jobs;
  395.  
  396. current_print_job = 0;
  397. more_print_jobs = 2;
  398. while (more_print_jobs)
  399. {
  400. if (current_print_job == 0)
  401. {
  402. P(my_semid, OK_TO_PRINT0);
  403. if (print_job[current_print_job] == -1)
  404. {
  405. more_print_jobs = more_print_jobs - 1;
  406. V(my_semid, OK_TO_SET_OUTPUT0);
  407. }
  408. else
  409. {
  410. memory_to_print = 20;
  411. print_memory(current_print_job, memory_to_print);
  412. print_job[current_print_job] = 0;
  413. V(my_semid, OK_TO_SET_OUTPUT0);
  414. }
  415. } /* end for current_print_job == 0 */
  416. else
  417. {
  418. P(my_semid, OK_TO_PRINT1);
  419. if (print_job[current_print_job] == -1)
  420. {
  421. more_print_jobs = more_print_jobs - 1;
  422. V(my_semid, OK_TO_SET_OUTPUT1);
  423. }
  424. else
  425. {
  426. memory_to_print = 30;
  427. print_memory(current_print_job, memory_to_print);
  428. print_job[current_print_job] = 0;
  429. V(my_semid, OK_TO_SET_OUTPUT1);
  430. }
  431. } /* end of else for current_print_job == 2 */
  432. current_print_job = (current_print_job + 1) % 2;
  433. } /* end of while */
  434. } /* end of printer */
  435.  
  436. void print_memory( current_print_job, memory_to_print)
  437. int current_print_job, memory_to_print;
  438. {
  439. int i;
  440.  
  441. strcpy(str1, "screen\n");
  442. strcpy(str2, "file\n");
  443.  
  444. if (strcmp(input, str1) == 0) {
  445. printf("output for current job %d \n", current_print_job);
  446. for ( i =1; i <= pcbs[current_print_job + 2].num_instructions; i++)
  447. {
  448. printf("%c %d %d %d \n", memory[memory_to_print].operation,
  449. memory[memory_to_print].operand1,
  450. memory[memory_to_print].operand2,
  451. memory[memory_to_print].result );
  452.  
  453. memory_to_print = memory_to_print + 1;
  454. }
  455. }
  456. else if (strcmp(input, str2) == 0) {
  457. fprintf(f,"output for current job %d \n", current_print_job);
  458. for ( i =1; i <= pcbs[current_print_job + 2].num_instructions; i++)
  459. {
  460. fprintf(f,"%c %d %d %d \n", memory[memory_to_print].operation,
  461. memory[memory_to_print].operand1,
  462. memory[memory_to_print].operand2,
  463. memory[memory_to_print].result );
  464.  
  465. memory_to_print = memory_to_print + 1;
  466. }
  467. }
  468. printf("\n\n");
  469. } /* end of print_memory */
  470.  
  471. #include "semshm.c"
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.c:50:1: error: initializer element is not constant
 FILE *f = fopen("cpu.output", "w");
 ^
prog.c:68:1: warning: return type defaults to ‘int’ [-Wreturn-type]
 main () 
 ^
prog.c: In function ‘main’:
prog.c:82:4: warning: implicit declaration of function ‘semtran’ [-Wimplicit-function-declaration]
    if ((my_semid = semtran(NUM_OF_SEMS)) != -1) 
    ^
prog.c:97:4: warning: implicit declaration of function ‘get_attach_shrmem’ [-Wimplicit-function-declaration]
    if ((get_attach_shrmem(size_of_memory,&my_shrmemaddr,
    ^
prog.c:107:4: warning: implicit declaration of function ‘wait’ [-Wimplicit-function-declaration]
    for (i = 1; i <= HOWMANY_PROCESSES; i++) wait(&s);
    ^
prog.c:113:4: warning: implicit declaration of function ‘exit’ [-Wimplicit-function-declaration]
    exit(0);
    ^
prog.c:113:4: warning: incompatible implicit declaration of built-in function ‘exit’ [enabled by default]
prog.c: In function ‘driver’:
prog.c:123:4: warning: implicit declaration of function ‘fork’ [-Wimplicit-function-declaration]
    if (( pid = fork() ) == -1) syserr("fork");
    ^
prog.c:129:7: warning: incompatible implicit declaration of built-in function ‘exit’ [enabled by default]
       exit(0);
       ^
prog.c:135:7: warning: incompatible implicit declaration of built-in function ‘exit’ [enabled by default]
       exit(0);
       ^
prog.c:141:7: warning: incompatible implicit declaration of built-in function ‘exit’ [enabled by default]
       exit(0);
       ^
prog.c: In function ‘fill_memory’:
prog.c:206:31: warning: variable ‘bad_instruction’ set but not used [-Wunused-but-set-variable]
    int opcode_ok, end_of_job, bad_instruction;
                               ^
prog.c:206:8: warning: variable ‘opcode_ok’ set but not used [-Wunused-but-set-variable]
    int opcode_ok, end_of_job, bad_instruction;
        ^
prog.c: In function ‘cpu’:
prog.c:271:8: warning: unused variable ‘memory_to_execute’ [-Wunused-variable]
    int memory_to_execute, current_job;
        ^
prog.c: In function ‘print_memory’:
prog.c:441:4: warning: implicit declaration of function ‘strcpy’ [-Wimplicit-function-declaration]
    strcpy(str1, "screen\n");
    ^
prog.c:441:4: warning: incompatible implicit declaration of built-in function ‘strcpy’ [enabled by default]
prog.c:444:4: warning: implicit declaration of function ‘strcmp’ [-Wimplicit-function-declaration]
    if (strcmp(input, str1) == 0) {
    ^
prog.c: At top level:
prog.c:471:20: fatal error: semshm.c: No such file or directory
 #include "semshm.c"
                    ^
compilation terminated.
stdout
Standard output is empty