Advertisement
DiegoDF1445

SO P&T - 5

Oct 22nd, 2018
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.91 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <pthread.h>
  5. #include <sys/types.h>
  6.  
  7. #define MAXN 100005
  8. #define THMAX 5
  9. #define min(x, y) (x <= y ? x : y)
  10.  
  11. //array que vai ser ordenado
  12. int arr[MAXN];
  13.  
  14. //mutex para tratar de regios criticas
  15. pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
  16. int flag = 0;
  17.  
  18. //pilha de threads disponiveis atualmente
  19. int stack[THMAX], top;
  20.  
  21. typedef struct{
  22.     int a, b, x, y, idx;
  23. }merge_range;
  24.  
  25. void* merge(void* data){
  26.     //Pego os intervalos em que eu vou juntar (merge)
  27.     merge_range *args = data;
  28.     int l = args-> a, r = args->b, i = args->x, j = args->y;
  29.     int val = args -> idx;
  30.  
  31.     //Variaveis auxiliares
  32.     int ord[MAXN], k, li = l, ls = j;
  33.  
  34.     //merge
  35.     for(k = l; l <= r && i <= j; k++){
  36.         if(arr[l] <= arr[i]) ord[k] = arr[l++];
  37.         else ord[k] = arr[i++];
  38.     }
  39.     while(l <= r) ord[k++] = arr[l++];
  40.     while(i <= j) ord[k++] = arr[i++];
  41.  
  42.     //atualizo meu array
  43.     for(; li <= ls; li++) arr[li] = ord[li];
  44.  
  45.     //região critica (variavel global), atualizo minha pilha de threads disponiveis
  46.     pthread_mutex_lock(&mtx);
  47.     stack[++top] = val;
  48.     pthread_mutex_unlock(&mtx);
  49.     return NULL;
  50. }
  51.  
  52. void merge_sort(int n){
  53.     //variaveis auxiliares
  54.     int i, j, qtd = 0, aux;
  55.     //threads
  56.     pthread_t thr[THMAX];
  57.     //array que vai guardar a task de cada thread em um instante da execução
  58.     merge_range tmp[THMAX];
  59.  
  60.     //Inicializo minha pilha de threads
  61.     for(i = 0; i < THMAX; i++) stack[i] = i;
  62.     top = THMAX - 1;
  63.  
  64.     for(i = 1; i <= n; i <<= 1){
  65.         for(j = 0; j + i <= n; j += (i << 1)  ){
  66.             //enquanto eu nao tiver threads disponiveis não faço nada
  67.             while(top < 0);
  68.             //Pego o indice da proxima thread disponivel
  69.             aux = stack[top];
  70.             //Inicializo os ranges que a thread ficara responsavel em dar o merge
  71.             tmp[ aux ].a = j; tmp[ aux ].b = j + i - 1;
  72.             tmp[ aux ].x = min(tmp[ aux ].b + 1, n - 1); tmp[aux].y = min(tmp[aux].x + i - 1, n - 1);
  73.             //Guardo o seu indice para ser recolado na pilha
  74.             tmp[aux].idx = stack[aux];
  75.  
  76.             //O trabalho começa
  77.             pthread_create( &thr[ aux ], NULL, &merge, &tmp[aux]);
  78.             pthread_join(thr[ stack[top--] ], NULL);
  79.  
  80.          }
  81.          //Enquanto todas as threads nao tiverem terminado seu trabalho, eu espero
  82.          while(top != THMAX - 1);
  83.     }
  84. }
  85.  
  86. int main(){
  87.     //Entrada e saida por arquivo
  88.     freopen("input.txt", "r", stdin);
  89.     freopen("output.txt", "w", stdout);
  90.  
  91.     //Tamanho do meu array
  92.     int n;
  93.     scanf("%d", &n);
  94.  
  95.     //Entrada dos elementos do array
  96.     int i;
  97.     for(i = 0; i < n; i++){
  98.         scanf("%d", arr + i);
  99.     }
  100.  
  101.     //MERGE SORT
  102.     merge_sort(n);
  103.  
  104.     //Printando array ordenado
  105.     for(i = 0; i < n; i++){
  106.         printf("%d ", arr[i]);
  107.     }
  108.     putchar('\n');
  109. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement