Advertisement
techno-

Ej 3 CP arreglado

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