Advertisement
Guest User

Lantz

a guest
Dec 16th, 2018
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.67 KB | None | 0 0
  1. /*
  2. Author: Jeremy Hutchins
  3. Class: CS530
  4. Professor: Scott Lindeneau
  5. Date: 12/16/2018
  6. Assignment: Program 2
  7. File: prog2_1.h
  8.  
  9. This header contains the structs for the linked list/queue implementation
  10. as well as method and mutex declarations to be used by prog2_1.c and prog2_2.c.
  11. */
  12.  
  13. #include <gmp.h>
  14. #include <pthread.h>
  15.  
  16. static pthread_mutex_t counterguard = PTHREAD_MUTEX_INITIALIZER; //Allows for threadsafe manipulation
  17.  
  18. //Nodes for the linked list. Will contain a pointer to the next node and a multi-precision number.
  19. typedef struct tsafenode {
  20. struct tsafenode *next;
  21. mpz_t number;
  22. } TSAFENODE ;
  23.  
  24. //Structure for the linked list itself.
  25. typedef struct tsafelist {
  26. pthread_mutex_t *mutex;
  27. TSAFENODE *head;
  28. } TSAFELIST;
  29.  
  30. //Struct for when dequeueing from the linked list.
  31. typedef struct tsafereturndata {
  32. //True(1)/False(0) if returned data is valid.
  33. int isValid;
  34. mpz_t value;
  35. } TSAFEDATA;
  36.  
  37. //Declarations for the 2 C files to use during execution.
  38. TSAFELIST * tSafeConstruct();
  39. void tSafeEnqueue(TSAFELIST * list, mpz_t data);
  40. TSAFEDATA* tSafeDequeue(TSAFELIST * list);
  41. void tSafeDestruct(TSAFELIST* list);
  42.  
  43.  
  44.  
  45. /*
  46. Author: Jeremy Hutchins
  47. Class: CS530
  48. Professor: Scott Lindeneau
  49. Date: 12/16/2018
  50. Assignment: Program 2
  51. File: prog2_1.c
  52.  
  53. This C file contains the functions for manipulating the linked list/queue.
  54. It will allocate and free memory as needed when adding and removing from
  55. the queue.
  56. */
  57.  
  58. #include "prog2_1.h"
  59. #include <pthread.h>
  60. #include <stdlib.h>
  61.  
  62. //Allocates memory and creates a new list.
  63. TSAFELIST * tSafeConstruct(){
  64. struct tsafenode* newNode = NULL;
  65. newNode = (struct tsafenode *)malloc(sizeof(struct tsafenode));
  66. TSAFELIST * list = (TSAFELIST*)malloc(sizeof(TSAFELIST));
  67. list->head = NULL;
  68. list->mutex = &counterguard;
  69.  
  70. return list;
  71. }
  72.  
  73. //Will free the memory associated with the created linked list
  74. void tSafeDestruct(TSAFELIST* list){
  75. TSAFENODE * currentNode = list->head;
  76. TSAFENODE * newNode = NULL;
  77. if(currentNode == NULL){
  78. free(currentNode);
  79. }else{
  80. while(currentNode->next !=NULL){
  81. newNode = currentNode-> next;
  82. free(currentNode);
  83. currentNode = newNode;
  84. }
  85. free(currentNode);
  86. }
  87. free(list);
  88. }
  89.  
  90. //Will add a node to the linked list at the tail
  91. void tSafeEnqueue(TSAFELIST * list, mpz_t data){
  92. TSAFENODE * currentNode;
  93. TSAFENODE * newNode = malloc(sizeof(TSAFENODE));
  94. mpz_init(newNode->number);
  95. if(list-> head == NULL){
  96. list->head = newNode;
  97. mpz_set(newNode->number,data);
  98. newNode->next=NULL;
  99. } else {
  100. currentNode = list->head;
  101. while(currentNode->next !=NULL){
  102. currentNode = currentNode->next;
  103. }
  104. currentNode->next = newNode;
  105. mpz_set(newNode->number,data);
  106. newNode->next=NULL;
  107. }
  108. }
  109.  
  110. //Will remove node from head and set head->next to head
  111. TSAFEDATA* tSafeDequeue(TSAFELIST * list){
  112. TSAFENODE * tempNode;
  113. TSAFEDATA * tempData = malloc(sizeof(TSAFEDATA));
  114. mpz_init(tempData->value);
  115.  
  116. if(list->head == NULL){
  117. tempData->isValid = 0;
  118. } else {
  119. tempData->isValid = 1;
  120. mpz_set(tempData->value,list->head->number);
  121. tempNode = list->head;
  122. list->head=list->head->next;
  123. }
  124. free(tempNode);
  125. return tempData;
  126. }
  127.  
  128.  
  129. /*
  130. Author: Jeremy Hutchins
  131. Class: CS530
  132. Professor: Scott Lindeneau
  133. Date: 12/16/2018
  134. Assignment: Program 2
  135. File: prog2_2.c
  136.  
  137. This program is the driver for prog.2_1.h and prog2_1.c.
  138. The program will take two arguments through the command line,
  139. verify that there are 2 supplied command line arguments, as
  140. well as verifying that they are integers, then find the first
  141. argv[1] numbers of bit-length argv[2] that are pseudoprimes.
  142.  
  143. Compilation of the program is: gcc
  144.  
  145. */
  146.  
  147. #include <stdlib.h>
  148. #include <stdio.h>
  149. #include <string.h>
  150. #include <pthread.h>
  151. #include <unistd.h>
  152. #include "prog2_1.h"
  153. #include <stdbool.h>
  154. #include <ctype.h>
  155.  
  156. static mpz_t globalCounter;
  157. static TSAFELIST *numberList;
  158. static int threadState = 0;
  159.  
  160. //This function will provide the next number to check in a thread-safe manner.
  161. void getNextNum(mpz_t num) {
  162. pthread_mutex_lock(&counterguard);
  163. mpz_set(num,globalCounter);
  164. mpz_add_ui(globalCounter,globalCounter,2);
  165. pthread_mutex_unlock(&counterguard);
  166. }
  167.  
  168. //This function will enqueue pseudoprimes in a continuous loop until
  169. //signalled by the main thread to stop.
  170. void *generatePrimes(void * arg) {
  171. int reps = 100000;
  172. int thId;
  173. int* pthread_state = arg;
  174. mpz_t numToCheck;
  175. mpz_init(numToCheck);
  176.  
  177. while(1) {
  178. usleep(10);
  179. switch (*pthread_state) {
  180. case 0:
  181. getNextNum(numToCheck);
  182. if(mpz_probab_prime_p(numToCheck,reps)>0) {
  183. tSafeEnqueue(numberList,numToCheck);
  184. }
  185.  
  186. usleep(10);
  187. break;
  188. case -1:
  189. pthread_exit(0);
  190. break;
  191. }
  192. }
  193. }
  194.  
  195. //This function will calculate the starting number to check based on the
  196. //commandline arguments provided.
  197. void initCounter(char* exponent) {
  198. mpz_t rop, base, exp, sub;
  199. mpz_inits ( rop, base, exp, sub, NULL );
  200. mpz_set_str ( base, "2", 10 );
  201. mpz_set_str ( sub, "1", 10 );
  202. mpz_set_str ( exp, exponent, 10 );
  203. mpz_sub ( exp, exp, sub );
  204. mpz_pow_ui (rop,base,mpz_get_ui(exp));
  205. if(mpz_even_p(rop))
  206. mpz_add(rop,rop,sub);
  207. mpz_set(globalCounter,rop);
  208.  
  209. mpz_clear(rop);
  210. mpz_clear(base);
  211. mpz_clear(exp);
  212.  
  213. }
  214.  
  215. //This is a helper function to validate commandline inputs.
  216. bool isNumber(char number[]){
  217. for(int i = 0; number[i] != 0; i++) {
  218. if(!isdigit(number[i]))
  219. return false;
  220. }
  221. return true;
  222. }
  223.  
  224. //This is the driver. It will create a linked list, start 4 threads, and run until
  225. //the quantity of numbers specified by argv[1] has been printed to STDOUT.
  226. int main(int argc, char * argv[]){
  227. if(argc==3 && atoi(argv[1])>=0 && atoi(argv[2])>=0 && isNumber(argv[1]) && isNumber(argv[2])){
  228. printf("Assignment #2-2, Jeremy Hutchins, mrjeremyhutchins@gmail.com\n");
  229.  
  230. TSAFEDATA * tempData = malloc(sizeof(TSAFEDATA));
  231. mpz_init(tempData->value);
  232. mpz_init(globalCounter);
  233. initCounter(argv[2]);
  234.  
  235. numberList = tSafeConstruct();
  236.  
  237. pthread_t t1,t2,t3,t4;
  238. pthread_create(&t1,NULL,generatePrimes,(void*)&threadState);
  239. pthread_create(&t2,NULL,generatePrimes,(void*)&threadState);
  240. pthread_create(&t3,NULL,generatePrimes,(void*)&threadState);
  241. pthread_create(&t4,NULL,generatePrimes,(void*)&threadState);
  242.  
  243. for(int i = 0; i<atoi(argv[1]);) {
  244. usleep(100);
  245. tempData = tSafeDequeue(numberList);
  246. if(tempData->isValid==1) {
  247. gmp_printf("%Zd\n",tempData->value);
  248. i++;
  249. }
  250. }
  251. threadState = -1;
  252. free(tempData);
  253. tSafeDestruct(numberList);
  254.  
  255. pthread_join(t1,NULL);
  256. pthread_join(t2,NULL);
  257. pthread_join(t3,NULL);
  258. pthread_join(t4,NULL);
  259.  
  260. mpz_clear(tempData->value);
  261. mpz_clear(globalCounter);
  262.  
  263. } else return -1;
  264. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement