Advertisement
techno-

ej 3 cp por acabar

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