Advertisement
techno-

ej3 cp hasta ahora

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