Advertisement
techno-

avance ej4 cp

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