Guest User

Untitled

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