Advertisement
KillianMills

hotel.c

Dec 5th, 2014
40
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.02 KB | None | 0 0
  1. //Killian Mills 11368701
  2. //Mark McCluskey 12514857
  3.  
  4. #include <pthread.h>
  5. #include <stdio.h>
  6. #include <signal.h>
  7. #include <stdlib.h>
  8. #include <time.h>
  9.  
  10. #define ETIMEDOUT 110
  11. #define HEAP_INITIAL_CAPACITY 1
  12.  
  13. typedef struct{
  14.     int expired; // number of wakeup calls that have taken place
  15.  
  16.     int size;   // elements currently in array
  17.     int capacity;   // limit of array or total size
  18.     long *data; // pointer to array of longs
  19.     int *room; // pointer to array of ints
  20.  
  21.     pthread_mutex_t mutex;
  22.     pthread_cond_t cond;
  23.  
  24. } Heap;
  25.  
  26. // constructor for our heap
  27. void heapInit(Heap *heap){
  28.  
  29.     heap->expired = 0;
  30.     heap->size = 0;
  31.     heap->capacity = HEAP_INITIAL_CAPACITY; // default heap size is 1
  32.     heap->data = malloc(sizeof(int) * heap->capacity);
  33.     heap->room = malloc(sizeof(int) * heap->capacity);
  34. }
  35.  
  36.  
  37. // doubles the size of the underlying data array capactiy if size >= capacity
  38. void heapDoubleSize(Heap *heap){
  39.  
  40.     if(heap->size >= heap->capacity-1){
  41.         heap->capacity *= 2;
  42.         heap->data = realloc(heap->data, sizeof(long) * heap->capacity);
  43.         heap->room = realloc(heap->room, sizeof(int) * heap->capacity);
  44.     }
  45. }
  46.  
  47. // restructure the tree as we add an element
  48. void fixUpHeap(Heap *heap, int position){
  49.  
  50.     int parent, temp,temp2;
  51.     if(position != 0){
  52.         parent = (position-1) / 2; 
  53.  
  54.         if(heap->data[parent] > heap->data[position]){
  55.             //swap
  56.             temp = heap->data[parent];
  57.             temp2 = heap->room[parent];
  58.  
  59.             heap->data[parent] = heap->data[position];
  60.             heap->room[parent] = heap->room[position];
  61.  
  62.             heap->data[position] = temp;
  63.             heap->room[position] = temp2;
  64.  
  65.             fixUpHeap( heap, parent);
  66.         }
  67.     }
  68. }
  69.  
  70. // inserts an element to the tree, calls fixUpHeap
  71. void insertHeap(Heap *heap,int roomN, long newAlarm){
  72.  
  73.     heapDoubleSize(heap);
  74.     heap->size++;
  75.     heap->data[heap->size-1] = newAlarm; // new alarm time
  76.     heap->room[heap->size-1] = roomN; // new room number
  77.     fixUpHeap(heap, heap->size-1);
  78. }
  79.  
  80. // restructure the tree as we remove an element
  81. void fixDownHeap(Heap *heap, int position){
  82.    
  83.     int left, right, min, temp,temp2;
  84.     left = 2* position +1;
  85.     right = 2* position +2;
  86.    
  87.     if(right>= heap->size){
  88.         if(left >= heap->size)
  89.             return;
  90.         else
  91.             min = left;
  92.     } else{
  93.         if(heap->data[left] <= heap->data[right])
  94.             min= left;
  95.         else
  96.             min = right;
  97.     }
  98.     if(heap->data[position] > heap->data[min]){
  99.         //swap
  100.         temp = heap->data[min];
  101.         temp2= heap->room[min];
  102.  
  103.         heap->data[min] = heap->data[position];
  104.         heap->room[min] = heap->room[position];
  105.  
  106.         heap->data[position] = temp;
  107.         heap->room[position] = temp2;
  108.  
  109.         fixDownHeap(heap, min);
  110.     }
  111. }
  112.  
  113. // removes an element from the tree, calls fixDownHeap
  114. void removeHeap(Heap *heap){
  115.  
  116.     if(heap->size!=0){
  117.         heap->data[0] = heap->data[heap->size-1];
  118.         heap->size--;
  119.         if(heap->size > 0){
  120.             fixDownHeap(heap, 0);
  121.         }
  122.     }
  123. }
  124.  
  125.  
  126. // frees the memory allocated to the data array
  127. void heapFree(Heap *heap){
  128.    
  129.     free(heap->data);
  130.     free(heap->room);
  131.     heap->size = 0;
  132.     heap->capacity = 0;
  133.     printf("Pending alarms: %d\n", heap->size);
  134. }
  135. //-----------END OF HEAP--------------
  136.  
  137.  
  138. // used to register random future alarms for hotel guests
  139. static void * generator(void *shared_in){
  140.  
  141.     //Bring struct into use
  142.     Heap *heapShared = (Heap *)shared_in;
  143.  
  144.     int roomNumber;
  145.  
  146.     while(1){
  147.         pthread_mutex_lock(&heapShared->mutex);
  148.    
  149.         srand (rand()%10000); //randomise
  150.         roomNumber = 1 + (rand() % 5000);
  151.         long alarmTime = time(NULL) + (rand() % 100);
  152.  
  153.         //add value to heap
  154.         printf("Registering:\t%d %s\n", roomNumber, ctime(&alarmTime));
  155.         insertHeap(heapShared,roomNumber,alarmTime);
  156.  
  157.         // if the first value is what we just submitted, alert the waker
  158.         if(alarmTime==heapShared->data[0]){
  159.             pthread_cond_signal(&heapShared->cond);
  160.  
  161.         }
  162.  
  163.         pthread_mutex_unlock(&heapShared->mutex);
  164.  
  165.         int randomSleep = rand() % 5000000;
  166.     usleep( randomSleep );
  167.  
  168.     }
  169.    
  170.     return ((void *)NULL);
  171. }
  172.  
  173.  
  174. // used to activate the alarms, wakes the hotel guests up
  175. static void * waker(void *shared_in){
  176.  
  177.     //Bring struct into use
  178.     Heap *heapShared = (Heap *)shared_in;
  179.     int randomValue;
  180.     int expired = 0;
  181.     int removeTime;
  182.     struct timespec timer;
  183.  
  184.     while(1){
  185.  
  186.         pthread_mutex_lock(&heapShared->mutex);
  187.  
  188.         //while no data to remove, wait
  189.         while(&heapShared->data[0] == NULL){
  190.             pthread_cond_wait(&heapShared->cond, &heapShared->mutex);
  191.  
  192.         }
  193.  
  194.         //sets the seconds equal to the array[0]
  195.         timer.tv_sec = heapShared->data[0];    
  196.         timer.tv_nsec = 0; 
  197.        
  198.         removeTime = pthread_cond_timedwait(&heapShared->cond, &heapShared->mutex, &timer);
  199.  
  200.         //if the value at [0] is the current time
  201.         if(removeTime == ETIMEDOUT){
  202.  
  203.             printf("Removing:\t%d %s\n",heapShared->room[0], ctime(&heapShared->data[0]));
  204.             removeHeap(heapShared);
  205.             heapShared->expired++;
  206.             printf("Pending Alarms: %d\n", heapShared->size);
  207.             printf("Expired Alarms: %d\n\n", heapShared->expired);
  208.  
  209.         }
  210.  
  211.         pthread_mutex_unlock(&heapShared->mutex);
  212.  
  213.     }
  214.  
  215.     return ((void *)NULL);
  216. }
  217.  
  218. int main(){
  219.     //Make generator and waker threads
  220.     pthread_t geneThread, wakeThread;
  221.  
  222.     //Start our heap
  223.     Heap mainHeap;
  224.     heapInit(&mainHeap);
  225.  
  226.     pthread_mutex_init(&mainHeap.mutex, NULL);
  227.     pthread_cond_init(&mainHeap.cond, NULL);
  228.  
  229.     //Create our threads
  230.     pthread_create(&geneThread, NULL, generator, (void *)&mainHeap);
  231.     pthread_create(&wakeThread, NULL, waker, (void *)&mainHeap);
  232.  
  233.     //Signal blocker
  234.     int sigHold; // hold the value of the current signal
  235.     sigset_t mainBlock;
  236.     sigemptyset(&mainBlock);
  237.     sigaddset(&mainBlock, SIGINT);
  238.     pthread_sigmask(SIG_BLOCK, &mainBlock, NULL); // block SIGINT
  239.     sigwait(&mainBlock,&sigHold);   // wait for SIGINT
  240.  
  241.     //Cancel our threads
  242.     pthread_cancel(geneThread);
  243.     pthread_cancel(wakeThread);
  244.  
  245.     printf("\n");
  246.  
  247.     //Wait for our threads
  248.     printf("The wake thread is cleaning up...\n");
  249.     pthread_join(geneThread, NULL);
  250.     printf("Goodbye from gene thread\n");
  251.  
  252.     printf("The gene thread is cleaning up...\n");
  253.     pthread_join(wakeThread, NULL);
  254.     printf("Goodbye from wake thread\n");
  255.  
  256.     pthread_mutex_destroy(&mainHeap.mutex);
  257.     heapFree(&mainHeap);
  258.  
  259.   return (0);
  260. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement