Guest User

Untitled

a guest
Nov 8th, 2019
76
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <pthread.h>
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <fcntl.h>
  7. #include <sys/shm.h>
  8. #include <sys/stat.h>
  9. #include <sys/mman.h>
  10. #include <sys/wait.h>
  11. #include <unistd.h>
  12. #include <errno.h>
  13. #include <time.h>
  14. #include <sys/types.h>
  15. #include <unistd.h>
  16. #include <semaphore.h>
  17.  
  18. #define THREAD_COUNT 3
  19. #define SIGINT 2
  20. #define SIGCONT 18
  21. #define SIGSTOP 19
  22. #define MEMBAR __sync_synchronize()
  23. volatile int tickets[THREAD_COUNT];
  24. volatile int choosing[THREAD_COUNT];
  25.  
  26.  
  27. int activeConnections = 0;
  28. int calculationComplete = 0;
  29. char* threeGrades, *threeWeights, gradeWeightAnswer[1024];
  30. int currentGrade[20];
  31. int currentWeight[20];
  32.  
  33. typedef struct {
  34. pthread_mutex_t mutex;
  35. sem_t fullR;
  36. sem_t emptyR;
  37. sem_t fullC;
  38. sem_t emptyC;
  39. sem_t fullP;
  40. sem_t emptyP;
  41. int threadNum;
  42. } Context;
  43.  
  44. Context* context2[4];
  45.  
  46. void* shmemAnswer[2];
  47. void* shmemConn[2];
  48. void *shmemGrades;
  49. void *shmemWeight;
  50. int shm_fdAnswer[2], shm_fdGrades, shm_fdWeight;
  51. int shm_fdConn[2];
  52. char* calcMultiple[8];
  53. int flag[2];
  54. int turn, count=0;
  55. void *retrieveMarksClient(void *param); /* threads call this function */
  56. void *retrieveMarksServer(void *param); /* threads call this function */
  57. void *calculateMarks(void *param);
  58. void *printMarks(void *param);
  59.  
  60. void *multiplyMarks(void *param1);
  61.  
  62. volatile int resource;
  63.  
  64. void lock(int current);
  65. void unlock(int current);
  66. void critical_section(int thread);
  67. int main(int argc, char *argv[])
  68. {
  69. pthread_t tidMult[3]; /* the thread identifier */
  70. pthread_attr_t attr, attr2, attr3; /* set of thread attributes */
  71. pid_t pid[10];
  72. resource = 0;
  73.  
  74. /* Start of using shared memory */
  75.  
  76. shm_fdConn[0] = shm_open("ServerConn1", O_CREAT | O_RDWR, 0666);
  77. shm_fdConn[1] = shm_open("ServerConn2", O_CREAT | O_RDWR, 0666);
  78. for (int i = 0; i < 2; i++) {
  79.  
  80. ftruncate(shm_fdConn[i], 1024);
  81.  
  82. shmemConn[i] = mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fdConn[i], 0);
  83.  
  84. }
  85. shm_fdGrades = shm_open("ServerClientGrades", O_CREAT | O_RDWR, 0666);
  86.  
  87. ftruncate(shm_fdGrades, 1024);
  88.  
  89. shmemGrades = mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fdGrades, 0);
  90.  
  91. shm_fdWeight = shm_open("ServerClientWeight", O_CREAT | O_RDWR, 0666);
  92.  
  93. ftruncate(shm_fdWeight, 1024);
  94.  
  95. shmemWeight = mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fdWeight, 0);
  96. shm_fdAnswer[0] = shm_open("ServerAnswer1", O_CREAT | O_RDWR, 0666);
  97. shm_fdAnswer[1] = shm_open("ServerAnswer2", O_CREAT | O_RDWR, 0666);
  98.  
  99. for (int i = 0; i < 2; i++) {
  100.  
  101. ftruncate(shm_fdAnswer[i], 1024);
  102.  
  103. shmemAnswer[i] = mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fdAnswer[i], 0);
  104. }
  105.  
  106. printf("Got here\n");
  107.  
  108. int shm_fdMult[6];
  109. shm_fdMult[0] = shm_open("SharedMemMult1", O_CREAT | O_RDWR, 0666);
  110. shm_fdMult[1] = shm_open("SharedMemMult2", O_CREAT | O_RDWR, 0666);
  111. shm_fdMult[2] = shm_open("SharedMemMult3", O_CREAT | O_RDWR, 0666);
  112. shm_fdMult[3] = shm_open("SharedMemMult4", O_CREAT | O_RDWR, 0666);
  113. shm_fdMult[4] = shm_open("SharedMemMult5", O_CREAT | O_RDWR, 0666);
  114. shm_fdMult[5] = shm_open("SharedMemMult6", O_CREAT | O_RDWR, 0666);
  115.  
  116.  
  117.  
  118.  
  119. /* End of using shared memory */
  120.  
  121.  
  122. Context context[10];
  123. int status = 0;
  124. for (int i = 0; i < 10; i++) {
  125. status = pthread_mutex_init(&context[i].mutex, NULL);
  126. status = sem_init(&context[i].fullR, 0, 0);
  127. status = sem_init(&context[i].emptyR, 0, 1);
  128. status = sem_init(&context[i].fullC, 0, 0);
  129. status = sem_init(&context[i].emptyC, 0, 0);
  130. status = sem_init(&context[i].fullP, 0, 0);
  131. status = sem_init(&context[i].emptyP, 0, 0);
  132. context->threadNum = i;
  133. }
  134.  
  135. int child;
  136. /* get the default attributes */
  137. int totalConnections = 0;
  138. while (totalConnections < 10)
  139. {
  140. if (activeConnections > 2) {
  141. printf("Too many active connections, waiting on child\n");
  142. wait(&child);
  143. }
  144. if (activeConnections == 1) {
  145. sprintf(shmemConn[0], "One");
  146. while(strstr((char*)shmemConn[0], "One") > 0) {
  147.  
  148. sleep(1);
  149. }
  150. sprintf(shmemConn[0], "%s", "Two");
  151. printf("Creating Server Instance\n");
  152. }
  153. else {
  154. printf("Waiting for client 2\n");
  155. sprintf(shmemConn[0], "Two");
  156. while(strstr((char*)shmemConn[0], "Two") > 0){
  157. sleep(1);
  158. }
  159. sprintf(shmemConn[0], "%s", "Two");
  160. printf("Creating Server Instance\n");
  161.  
  162. }
  163. pid[totalConnections] = fork();
  164. if(pid[totalConnections] == 0) { //Child Process
  165. printf("Server 1\n");
  166. pthread_t tid, tid2, tid3;
  167. activeConnections++;
  168. printf("Server 1 started\n");
  169. /* get the default attributes */
  170. int rc = pthread_create(&tid,NULL, &retrieveMarksServer, &context[totalConnections]);
  171. if (rc != 0) {
  172. errno = rc;
  173. perror("child: pthread create");
  174. exit(1);
  175. }
  176. int rc2 = pthread_create(&tid3,NULL, &calculateMarks, &context[totalConnections]);
  177. if (rc2 != 0) {
  178. errno = rc;
  179. perror("child: pthread create");
  180. exit(1);
  181. }
  182. int rc3 = pthread_create(&tid2,NULL, &printMarks, &context[totalConnections]);
  183. if (rc3 != 0) {
  184. errno = rc3;
  185. perror("child: pthread create");
  186. exit(1);
  187. }
  188. printf("Waiting for threads to join\n");
  189. //pthread_create(&tid2,&attr2, &printMarks, &context);
  190. /* create the threads for the server */
  191. void *status;
  192. int rc4 = pthread_join(tid, &status);
  193. if (rc4 != 0) {
  194. errno = rc4;
  195. perror("child: pthread_join");
  196. exit(1);
  197. }
  198.  
  199. int rc5 = pthread_join(tid3, &status);
  200. if (rc5 != 0) {
  201. errno = rc4;
  202. perror("child: pthread_join");
  203. exit(1);
  204. }
  205. int rc6 = pthread_join(tid2, &status);
  206. if (rc6 != 0) {
  207. errno = rc6;
  208. perror("child: pthread_join");
  209. exit(1);
  210. }
  211. printf("Current printed to shmemAnswer0 is end %s\n", shmemAnswer[0]);
  212. printf("Current printed to shmemAnswer1 is end %s\n", shmemAnswer[1]);
  213.  
  214. printf("Cleaned up answer shared memory\n");
  215. activeConnections--;
  216. exit(0);
  217. }
  218. else if(pid[totalConnections] == -1) {
  219. printf("Error");
  220. }
  221. else { //parent process
  222.  
  223. printf("Server waiting for the child\n");
  224. //pid_t waitForChild = wait(&child);
  225. //if (waitForChild == -1) {
  226. // perror("there was an error\n");
  227. // exit(1);
  228. // }
  229.  
  230. if (WIFEXITED(child)) {
  231. fprintf(stderr, "parent: child exited: %d\n", WEXITSTATUS(child));
  232. } else if (WIFSIGNALED(child)) {
  233. fprintf(stderr, "parent: child exited with signal: %s\n", strsignal(WTERMSIG(child)));
  234. } else {
  235. fprintf(stderr, "parent: child exited with status: %d\n", child);
  236. }
  237.  
  238. printf("Done waiting for child\n");
  239. totalConnections++;
  240.  
  241. printf("Exiting Server Thread\n");
  242. }
  243. }
  244. pthread_exit(NULL);
  245. //kill(pid[0], SIGINT);
  246. //printf("sum = %d\n",sum);
  247. exit(0);
  248. }
  249.  
  250.  
  251. /* The thread will begin control in this function */
  252. void *retrieveMarksClient(void *param)
  253. {
  254.  
  255. /*pointer used for access to shared memory segment */
  256. char sum[1024];
  257. char weights[1024];
  258. Context* context = (Context*) param;
  259.  
  260. sem_wait(&context->emptyR);
  261. //pthread_mutex_lock(&(context->mutex));
  262. printf("List your three grades, separated by a comma (eg. 95,85,75)\n");
  263. fgets(sum, sizeof sum, stdin);
  264. sprintf(threeGrades, sum);
  265. printf("List the weighting of each of these grades (eg 30, 30, 40)\n");
  266. fgets(weights, sizeof weights, stdin);
  267. sprintf(threeWeights, weights);
  268. //pthread_mutex_unlock(&(context->mutex));
  269. sem_post(&context->emptyP);
  270. return NULL;
  271. }
  272. void *retrieveMarksServer(void *param)
  273. {
  274.  
  275. /*pointer used for access to shared memory segment */
  276. char sum[1024];
  277. char weights[1024];
  278. printf("The retrieve numbers started\n");
  279. Context* context = (Context*) param;
  280. //wait for the signal from client, the post to server calculate
  281. //sprintf(shmem3, "Server: start of retrieve");
  282. while(strlen((char*) shmemWeight) < 2){
  283. sleep(1);
  284. printf("Waiting for buffer to fill, shmemWeight %s \n", shmemWeight);
  285. }
  286.  
  287.  
  288. printf("Received numbers\n");
  289. sem_post(&context->fullR);
  290. //sprintf(shmem3, "Server: end of retrieve");
  291. return NULL;
  292. }
  293.  
  294. /* The thread will begin control in this function */
  295. void *calculateMarks(void *param)
  296. {
  297.  
  298. pthread_t tidMult[4];
  299. pthread_attr_t attMult[4];
  300. float numberGrades, weightGrades;
  301. float lastGrade;
  302. int count = 0;
  303.  
  304.  
  305. char* saveptr1 = NULL;
  306. char* token = NULL;
  307.  
  308. char* saveptr2 = NULL;
  309. char* token2 = NULL;
  310.  
  311. Context* context = (Context*) param;
  312.  
  313. sem_wait(&context->fullR);
  314.  
  315. printf("Threads started calculating\n");
  316. printf("Shmem grades %s end\n", shmemGrades);
  317.  
  318. int calcSpot1 = 0;
  319. char theGrades[120];
  320. sprintf(theGrades, "%s", shmemGrades);
  321. printf(" %s\n", theGrades);
  322. printf("%d\n", theGrades[0]);
  323. printf("%d\n", theGrades[1]);
  324. char* strptr;
  325. token = strtok_r(theGrades, ",", &strptr);
  326. currentGrade[0] = atoi(token);
  327. currentGrade[1] = atoi(strtok_r(NULL, ",", &strptr));
  328. currentGrade[2] = atoi(strtok_r(NULL, ",", &strptr));
  329. printf("Midway calculating\n");
  330. char theWeights[120];
  331. sprintf(theWeights, "%s", shmemWeight);
  332. token2 = strtok(theWeights, ",");
  333. //token2 = strtok_r(NULL, ",", &saveptr2);
  334. currentWeight[0] = atoi(token2);
  335. currentWeight[1] = atoi(strtok(NULL, ","));
  336. currentWeight[2] = atoi(strtok(NULL, ","));
  337.  
  338. for (int k = 0; k < THREAD_COUNT; k++) {
  339. pthread_create(&tidMult[k], NULL, &multiplyMarks, (void*) ((long) k) );
  340. }
  341. for (int m = 0; m < THREAD_COUNT; m++) {
  342. pthread_join(tidMult[m],NULL);
  343. }
  344.  
  345. printf("Threads done calculating\n");
  346.  
  347. sem_post(&context->emptyP);
  348.  
  349. return NULL;
  350. }
  351.  
  352. void *multiplyMarks(void *param1) {
  353.  
  354. long thread = (long) param1;
  355. lock(thread);
  356. critical_section(thread);
  357. unlock(thread);
  358. return NULL;
  359. }
  360.  
  361. void critical_section(int thread) {
  362.  
  363. float totalMark;
  364. int retrieve;
  365. retrieve = thread * 2;
  366. int retrieve2;
  367. retrieve2 = thread * 2 + 1;
  368. printf("in the critical section %d thread\n", thread);
  369. //printf("threadNum %d", context->threadNum);
  370. printf("shmem %d\n", currentGrade[0]);
  371. printf("shmem %d\n", currentWeight[0]);
  372. totalMark = atof(gradeWeightAnswer) + ((float) currentGrade[0]) * ((float) currentWeight[0]) / 100.0f;
  373. printf("end of calculation in critical section\n");
  374. sprintf(gradeWeightAnswer, "%f", totalMark);
  375. printf("end of critical section\n");
  376.  
  377. }
  378.  
  379. void *printMarks(void *param)
  380. {
  381. float currentGrade[20];
  382. float numberGrades = 0.0;
  383. float lastGrade;
  384. int count = 0;
  385. Context* context = (Context*) param;
  386. //while (1)
  387. //{
  388. sem_wait(&context->emptyP);
  389.  
  390.  
  391. if (activeConnections == 1) {
  392. sprintf(shmemAnswer[0], gradeWeightAnswer);
  393. }
  394. else if(activeConnections == 2)
  395. {
  396. sprintf(shmemAnswer[1], gradeWeightAnswer);
  397. } //sem_post(&context->emptyP);
  398. //}
  399. return NULL;
  400. }
  401. void lock(int thread)
  402. {
  403.  
  404. // Before getting the ticket number
  405. //"choosing" variable is set to be true
  406. choosing[thread] = 1;
  407.  
  408. MEMBAR;
  409. // Memory barrier applied
  410.  
  411. int max_ticket = 0;
  412.  
  413. // Finding Maximum ticket value among current threads
  414. for (int i = 0; i < THREAD_COUNT; ++i) {
  415.  
  416. int ticket = tickets[i];
  417. max_ticket = ticket > max_ticket ? ticket : max_ticket;
  418. }
  419.  
  420. // Allotting a new ticket value as MAXIMUM + 1
  421. tickets[thread] = max_ticket + 1;
  422.  
  423. MEMBAR;
  424. choosing[thread] = 0;
  425. MEMBAR;
  426.  
  427. // The ENTRY Section starts from here
  428. for (int other = 0; other < THREAD_COUNT; ++other) {
  429.  
  430. // Applying the bakery algorithm conditions
  431. while (choosing[other]) {
  432. }
  433.  
  434. MEMBAR;
  435.  
  436. while (tickets[other] != 0 && (tickets[other]
  437. < tickets[thread]
  438. || (tickets[other]
  439. == tickets[thread]
  440. && other < thread))) {
  441. }
  442. }
  443. }
  444.  
  445. // EXIT Section
  446. void unlock(int thread)
  447. {
  448.  
  449. MEMBAR;
  450. tickets[thread] = 0;
  451. }
RAW Paste Data