Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Author: Jeremy Hutchins
- Class: CS530
- Professor: Scott Lindeneau
- Date: 12/16/2018
- Assignment: Program 2
- File: prog2_1.h
- This header contains the structs for the linked list/queue implementation
- as well as method and mutex declarations to be used by prog2_1.c and prog2_2.c.
- */
- #include <gmp.h>
- #include <pthread.h>
- static pthread_mutex_t counterguard = PTHREAD_MUTEX_INITIALIZER; //Allows for threadsafe manipulation
- //Nodes for the linked list. Will contain a pointer to the next node and a multi-precision number.
- typedef struct tsafenode {
- struct tsafenode *next;
- mpz_t number;
- } TSAFENODE ;
- //Structure for the linked list itself.
- typedef struct tsafelist {
- pthread_mutex_t *mutex;
- TSAFENODE *head;
- } TSAFELIST;
- //Struct for when dequeueing from the linked list.
- typedef struct tsafereturndata {
- //True(1)/False(0) if returned data is valid.
- int isValid;
- mpz_t value;
- } TSAFEDATA;
- //Declarations for the 2 C files to use during execution.
- TSAFELIST * tSafeConstruct();
- void tSafeEnqueue(TSAFELIST * list, mpz_t data);
- TSAFEDATA* tSafeDequeue(TSAFELIST * list);
- void tSafeDestruct(TSAFELIST* list);
- /*
- Author: Jeremy Hutchins
- Class: CS530
- Professor: Scott Lindeneau
- Date: 12/16/2018
- Assignment: Program 2
- File: prog2_1.c
- This C file contains the functions for manipulating the linked list/queue.
- It will allocate and free memory as needed when adding and removing from
- the queue.
- */
- #include "prog2_1.h"
- #include <pthread.h>
- #include <stdlib.h>
- //Allocates memory and creates a new list.
- TSAFELIST * tSafeConstruct(){
- struct tsafenode* newNode = NULL;
- newNode = (struct tsafenode *)malloc(sizeof(struct tsafenode));
- TSAFELIST * list = (TSAFELIST*)malloc(sizeof(TSAFELIST));
- list->head = NULL;
- list->mutex = &counterguard;
- return list;
- }
- //Will free the memory associated with the created linked list
- void tSafeDestruct(TSAFELIST* list){
- TSAFENODE * currentNode = list->head;
- TSAFENODE * newNode = NULL;
- if(currentNode == NULL){
- free(currentNode);
- }else{
- while(currentNode->next !=NULL){
- newNode = currentNode-> next;
- free(currentNode);
- currentNode = newNode;
- }
- free(currentNode);
- }
- free(list);
- }
- //Will add a node to the linked list at the tail
- void tSafeEnqueue(TSAFELIST * list, mpz_t data){
- TSAFENODE * currentNode;
- TSAFENODE * newNode = malloc(sizeof(TSAFENODE));
- mpz_init(newNode->number);
- if(list-> head == NULL){
- list->head = newNode;
- mpz_set(newNode->number,data);
- newNode->next=NULL;
- } else {
- currentNode = list->head;
- while(currentNode->next !=NULL){
- currentNode = currentNode->next;
- }
- currentNode->next = newNode;
- mpz_set(newNode->number,data);
- newNode->next=NULL;
- }
- }
- //Will remove node from head and set head->next to head
- TSAFEDATA* tSafeDequeue(TSAFELIST * list){
- TSAFENODE * tempNode;
- TSAFEDATA * tempData = malloc(sizeof(TSAFEDATA));
- mpz_init(tempData->value);
- if(list->head == NULL){
- tempData->isValid = 0;
- } else {
- tempData->isValid = 1;
- mpz_set(tempData->value,list->head->number);
- tempNode = list->head;
- list->head=list->head->next;
- }
- free(tempNode);
- return tempData;
- }
- /*
- Author: Jeremy Hutchins
- Class: CS530
- Professor: Scott Lindeneau
- Date: 12/16/2018
- Assignment: Program 2
- File: prog2_2.c
- This program is the driver for prog.2_1.h and prog2_1.c.
- The program will take two arguments through the command line,
- verify that there are 2 supplied command line arguments, as
- well as verifying that they are integers, then find the first
- argv[1] numbers of bit-length argv[2] that are pseudoprimes.
- Compilation of the program is: gcc
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <pthread.h>
- #include <unistd.h>
- #include "prog2_1.h"
- #include <stdbool.h>
- #include <ctype.h>
- static mpz_t globalCounter;
- static TSAFELIST *numberList;
- static int threadState = 0;
- //This function will provide the next number to check in a thread-safe manner.
- void getNextNum(mpz_t num) {
- pthread_mutex_lock(&counterguard);
- mpz_set(num,globalCounter);
- mpz_add_ui(globalCounter,globalCounter,2);
- pthread_mutex_unlock(&counterguard);
- }
- //This function will enqueue pseudoprimes in a continuous loop until
- //signalled by the main thread to stop.
- void *generatePrimes(void * arg) {
- int reps = 100000;
- int thId;
- int* pthread_state = arg;
- mpz_t numToCheck;
- mpz_init(numToCheck);
- while(1) {
- usleep(10);
- switch (*pthread_state) {
- case 0:
- getNextNum(numToCheck);
- if(mpz_probab_prime_p(numToCheck,reps)>0) {
- tSafeEnqueue(numberList,numToCheck);
- }
- usleep(10);
- break;
- case -1:
- pthread_exit(0);
- break;
- }
- }
- }
- //This function will calculate the starting number to check based on the
- //commandline arguments provided.
- void initCounter(char* exponent) {
- mpz_t rop, base, exp, sub;
- mpz_inits ( rop, base, exp, sub, NULL );
- mpz_set_str ( base, "2", 10 );
- mpz_set_str ( sub, "1", 10 );
- mpz_set_str ( exp, exponent, 10 );
- mpz_sub ( exp, exp, sub );
- mpz_pow_ui (rop,base,mpz_get_ui(exp));
- if(mpz_even_p(rop))
- mpz_add(rop,rop,sub);
- mpz_set(globalCounter,rop);
- mpz_clear(rop);
- mpz_clear(base);
- mpz_clear(exp);
- }
- //This is a helper function to validate commandline inputs.
- bool isNumber(char number[]){
- for(int i = 0; number[i] != 0; i++) {
- if(!isdigit(number[i]))
- return false;
- }
- return true;
- }
- //This is the driver. It will create a linked list, start 4 threads, and run until
- //the quantity of numbers specified by argv[1] has been printed to STDOUT.
- int main(int argc, char * argv[]){
- if(argc==3 && atoi(argv[1])>=0 && atoi(argv[2])>=0 && isNumber(argv[1]) && isNumber(argv[2])){
- printf("Assignment #2-2, Jeremy Hutchins, mrjeremyhutchins@gmail.com\n");
- TSAFEDATA * tempData = malloc(sizeof(TSAFEDATA));
- mpz_init(tempData->value);
- mpz_init(globalCounter);
- initCounter(argv[2]);
- numberList = tSafeConstruct();
- pthread_t t1,t2,t3,t4;
- pthread_create(&t1,NULL,generatePrimes,(void*)&threadState);
- pthread_create(&t2,NULL,generatePrimes,(void*)&threadState);
- pthread_create(&t3,NULL,generatePrimes,(void*)&threadState);
- pthread_create(&t4,NULL,generatePrimes,(void*)&threadState);
- for(int i = 0; i<atoi(argv[1]);) {
- usleep(100);
- tempData = tSafeDequeue(numberList);
- if(tempData->isValid==1) {
- gmp_printf("%Zd\n",tempData->value);
- i++;
- }
- }
- threadState = -1;
- free(tempData);
- tSafeDestruct(numberList);
- pthread_join(t1,NULL);
- pthread_join(t2,NULL);
- pthread_join(t3,NULL);
- pthread_join(t4,NULL);
- mpz_clear(tempData->value);
- mpz_clear(globalCounter);
- } else return -1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement