Advertisement
techno-

ej4 cp

Feb 11th, 2023
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.98 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <time.h>
  5. #include "options.h"
  6. #include <threads.h>
  7.  
  8. #define DELAY_SCALE 1000
  9.  
  10. int contIncremento=0;
  11. int contSumaResta=0;
  12. mtx_t *mutexContIncremento;
  13. mtx_t *mutexContSumaResta;
  14.  
  15. int num_threadsG;
  16.  
  17. //Added mutex to the array struct
  18. struct array {
  19.     int size;
  20.     int *arr;
  21.     mtx_t* mutex;
  22. };
  23.  
  24. //args to create the threads
  25. struct args {
  26.     int id;
  27.     int iterations;
  28.     int delay;
  29.     int increase;
  30.     struct array*array;
  31. };
  32.  
  33. //Info regarding the threads
  34. struct thread_info {
  35.     thrd_t id;
  36.     struct args*args;
  37. };
  38.  
  39.  
  40. void apply_delay(int delay) {
  41.     for(int i = 0; i < delay * DELAY_SCALE; i++); // waste time
  42. }
  43.  
  44.  
  45. int increment(int id, int iterations, int delay, struct array *arr)
  46. {
  47.     int pos, val;
  48.  
  49.     for(int i = 0; i < iterations; i++) {
  50.         pos = rand() % arr->size;
  51.  
  52.         printf("%d increasing position %d\n", id, pos);
  53.  
  54.         val = arr->arr[pos];
  55.         apply_delay(delay);
  56.  
  57.         val ++;
  58.         apply_delay(delay);
  59.  
  60.         arr->arr[pos] = val;
  61.         apply_delay(delay);
  62.     }
  63.  
  64.     return 0;
  65. }
  66.  
  67. int resta_suma(void *ptr){
  68.     struct args*args = ptr;
  69.     int pos1, pos2, val, iteraciones, i;
  70.     iteraciones= (rand() % (args->iterations - args->iterations/num_threadsG + 1)) + args->iterations/num_threadsG;
  71.    
  72.     for(i=0;i<iteraciones;i++){
  73.    
  74.         if(contSumaResta<args->iterations){
  75.             mtx_lock(mutexContSumaResta);
  76.             contSumaResta++;
  77.             mtx_unlock(mutexContSumaResta);
  78.        
  79.             pos1 = rand() % args->array->size;
  80.             pos2 = rand() % args->array->size;
  81.        
  82.             while(pos1==pos2){
  83.                 pos1 = rand() % args->array->size;
  84.                 pos2 = rand() % args->array->size;
  85.             }
  86.        
  87.             printf("pos2 es %d\n",pos2);
  88.             printf("Thread %d decrementa la posición %d e incrementa la posición %d\n",args->id, pos1, pos2);
  89.        
  90.             if(pos1<pos2){
  91.             mtx_lock(&args->array->mutex[pos1]);
  92.             mtx_lock(&args->array->mutex[pos2]);
  93.             }
  94.             else{
  95.             mtx_lock(&args->array->mutex[pos2]);
  96.             mtx_lock(&args->array->mutex[pos1]);   
  97.             }
  98.        
  99.             val = args->array->arr[pos1];
  100.             apply_delay(args->delay);
  101.             val--;
  102.             apply_delay(args->delay);
  103.             args->array->arr[pos1]=val;
  104.        
  105.             val = args->array->arr[pos2];
  106.             apply_delay(args->delay);
  107.             val++;
  108.             apply_delay(args->delay);
  109.             args->array->arr[pos2]=val;
  110.        
  111.             if(pos1<pos2){
  112.             mtx_unlock(&args->array->mutex[pos1]);
  113.             mtx_unlock(&args->array->mutex[pos2]);
  114.             }
  115.             else{
  116.             mtx_unlock(&args->array->mutex[pos2]);
  117.             mtx_unlock(&args->array->mutex[pos1]); 
  118.             }
  119.         }
  120.    
  121.     }
  122.    
  123.     return 0;
  124. }
  125.  
  126. //How it's supposed to work: lock the access to the array. Increment the position, add the increase to the
  127. //  args->increase section to know how much is increased by every thread and unlock after certain delay.
  128. int aux_increment(void*ptr){
  129.     struct args*args = ptr;
  130.     int pos,val,i, iteraciones;
  131.     iteraciones= (rand() % (args->iterations - args->iterations/num_threadsG + 1)) + args->iterations/num_threadsG;
  132.     for(i=0;i<iteraciones;i++){
  133.                 if(contIncremento<args->iterations){
  134.            
  135.                 mtx_lock(mutexContIncremento);
  136.                 contIncremento++;
  137.                 mtx_unlock(mutexContIncremento);
  138.  
  139.                 pos = rand() % args->array->size;
  140.                 printf("Thread %d increasing position %d.\n", args->id, pos);
  141.                 mtx_lock(&args->array->mutex[pos]);
  142.                 val = args->array->arr[pos];
  143.                 apply_delay(args->delay);
  144.                 val++;
  145.                 args->increase ++;
  146.                 apply_delay(args->delay);
  147.                 args->array->arr[pos] = val;
  148.                 apply_delay(args->delay);
  149.                 mtx_unlock(&args->array->mutex[pos]);
  150.            
  151.                
  152.             }
  153.         }
  154.     return 0;
  155. }
  156.  
  157. //Print the array to check if the corresponding amounts are correct.
  158. void print_array(struct array*arr, struct thread_info*thred, int num_threads) {
  159.     int total = 0;
  160.  
  161.     //Print by thread
  162.     for(int i = 0; i < num_threads; i++) {
  163.         printf("%d: %d.\n",i,thred[i].args->increase);
  164.     }
  165.     //Print by array
  166.     for(int i = 0; i < arr->size; i++) {
  167.         total += arr->arr[i];
  168.         printf("%d ", arr->arr[i]);
  169.     }
  170.  
  171.     printf("\nSuma total del array: %d\n", total);
  172. }
  173.  
  174. //Start threads function.
  175. struct thread_info* start_threads(struct options opt, struct array*array){
  176.     int i;
  177.     struct thread_info* threads;
  178.     printf("Creating %d threads.\n", opt.num_threads*2);
  179.     threads = malloc(sizeof(struct thread_info)*opt.num_threads*2);
  180.  
  181.     if(threads == NULL){
  182.         printf("Not enough memory available.\n");
  183.         exit(1);
  184.     }
  185.  
  186.     for(i = 0; i < opt.num_threads; i++){
  187.         threads[i].args = malloc(sizeof(struct args));
  188.         threads[i].args -> id = i;
  189.         threads[i].args -> increase = 0;
  190.         threads[i].args -> iterations = opt.iterations;
  191.         threads[i].args -> delay = opt.delay;
  192.         threads[i].args -> array = array;
  193.  
  194.         if( 0!= thrd_create(&threads[i].id,aux_increment,threads[i].args));
  195.     }
  196.     printf("LLEGA\n");
  197.    
  198.     for(i = opt.num_threads; i < opt.num_threads*2; i++){
  199.         threads[i].args = malloc(sizeof(struct args));
  200.         threads[i].args -> id = i;
  201.         threads[i].args -> increase = 0;
  202.         threads[i].args -> iterations = opt.iterations;
  203.         threads[i].args -> delay = opt.delay;
  204.         threads[i].args -> array = array;
  205.  
  206.         if( 0!= thrd_create(&threads[i].id,resta_suma,threads[i].args));
  207.     }
  208.     return threads;
  209. }
  210.  
  211. //Wait function, so we can make sure every thread has finished at the end of the program.
  212. void wait (struct options opt, struct array*array, struct thread_info* threads){
  213.     for(int i = 0; i < (opt.num_threads*2); i++){
  214.         thrd_join(threads[i].id,NULL);
  215.     }
  216.     print_array(array,threads,opt.num_threads*2);
  217.  
  218.     for(int i = 0; i < (opt.num_threads*2); i++){
  219.         free(threads[i].args);
  220.     }
  221.  
  222.     free(threads);
  223.     free(array->arr);
  224. }
  225.  
  226. //Function that makes sure the mutex, array and threads are properly initialized.
  227. void init_arrays(struct array*array, int size){
  228.     array->size = size;
  229.     array->arr = malloc(array->size*sizeof(int));
  230.     array->mutex = malloc(size* sizeof (mtx_t));
  231.  
  232.     for(int i = 0; i<array->size; i++){
  233.         array->arr[i] = 0;
  234.         mtx_init(&array->mutex[i],mtx_plain);
  235.     }
  236. }
  237.  
  238. //Main function.
  239. int main (int argc, char **argv)
  240. {
  241.     mutexContIncremento= malloc(sizeof(mtx_t));
  242.     mutexContSumaResta= malloc(sizeof(mtx_t));
  243.     mtx_init(mutexContIncremento, mtx_plain);
  244.     mtx_init(mutexContSumaResta, mtx_plain);
  245.     struct options       opt;
  246.     struct array         arr;
  247.     struct thread_info * thred;
  248.  
  249.     srand(time(NULL));
  250.  
  251.     // Default values for the options
  252.     opt.num_threads  = 5;
  253.     opt.size         = 10;
  254.     opt.iterations   = 100;
  255.     opt.delay        = 1000;
  256.    
  257.     num_threadsG= opt.num_threads;
  258.     read_options(argc, argv, &opt);
  259.  
  260.  
  261.     init_arrays(&arr,opt.size);
  262.  
  263.     thred = start_threads(opt,&arr);
  264.     wait(opt,&arr,thred);
  265.    
  266.     mtx_destroy(mutexContIncremento);
  267.     mtx_destroy(mutexContSumaResta);
  268.     printf("\nTotal de incrementos: %d\n",contIncremento);
  269.     printf("Total de resta-suma: %d\n",contSumaResta);
  270.  
  271.     return 0;
  272. }
  273.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement