#include #include #include #include #include //#define KRATKI_SEZNAM #define T 8 #ifdef KRATKI_SEZNAM #define N 13 #else #define N 33 #endif typedef struct{ int threadID; int idxStart; int iBlockSize; } thread_args_t; typedef enum { false = 0, true = 1 } bool_t; pthread_t nit[T]; pthread_barrier_t barrier; thread_args_t args[T]; bool_t bSortedGlobal = true; void* funkcija_niti(void* args); void *(*pFunkcijaNiti)(void*) = funkcija_niti; pthread_mutex_t kljucavnica = PTHREAD_MUTEX_INITIALIZER; time_t seconds; #ifdef KRATKI_SEZNAM //unsigned int seznam[] = {7,4,3,6,5,2,8,9,1,0,10,12,11}; unsigned int seznam[] = {0,2,1,3,4,5,6,7,8,9,10,11,12}; #else unsigned int seznam[N]; #endif unsigned int *pSeznam = &seznam[0]; void izpisi_seznam(unsigned int *pSeznam){ for (int i = 0; i < N; i++) { printf("%d ", *(pSeznam+i)); } printf("\n"); } bool_t primerjaj_in_zamenjaj(unsigned int* a, unsigned int* b){ bool_t bSorted = true; unsigned int temp; if (*b < *a) { temp = *a; *a = *b; *b = temp; bSorted = false; } return bSorted; } bool_t sodi_prehod(int iBlockSize, unsigned int* pSeznam, int threadID){ bool_t bSorted = true; int iStart= (threadID*(N/T))%2; for (int i = iStart; i < iBlockSize; i=i+2){ bSorted = bSorted & primerjaj_in_zamenjaj(&pSeznam[i], &pSeznam[i+1]); } return bSorted; } bool_t lihi_prehod(int iBlockSize, unsigned int* pSeznam, int threadID){ bool_t bSorted = true; int iStart = (threadID*(N/T))%2; for (int i = 1 - iStart; i < iBlockSize; i=i+2){ bSorted = bSorted & primerjaj_in_zamenjaj(&pSeznam[i], &pSeznam[i+1]); } return bSorted; } void *funkcija_niti(void* arg){ bool_t bSorted = true; thread_args_t* args = (thread_args_t*) arg; for (int i = 0; i < N; i++) { bSorted = true; bSorted = bSorted & sodi_prehod(args->iBlockSize, pSeznam + (args->idxStart), args->threadID); pthread_mutex_lock(&kljucavnica); bSortedGlobal = bSortedGlobal & bSorted; pthread_mutex_unlock(&kljucavnica); printf("SODI: T%d, i=%d bSorted=%d\n", args->threadID, i, bSorted); pthread_barrier_wait(&barrier); /****************** P R E P R E K A ******************/ bSorted = true; bSorted = bSorted & lihi_prehod(args->iBlockSize, pSeznam + (args->idxStart), args->threadID); pthread_mutex_lock(&kljucavnica); bSortedGlobal = bSortedGlobal & bSorted; pthread_mutex_unlock(&kljucavnica); printf("LIHI: T%d, i=%d bSorted=%d\n", args->threadID, i, bSorted); pthread_barrier_wait(&barrier); /****************** P R E P R E K A ******************/ if (bSortedGlobal == true) { break; } pthread_barrier_wait(&barrier); /****************** P R E P R E K A ******************/ if(args->threadID == 0) { bSortedGlobal = true; } pthread_barrier_wait(&barrier); /****************** P R E P R E K A ******************/ } } int main(){ #ifndef KRATKI_SEZNAM // init random generatorja: srand((unsigned) time(&seconds)); //init seznama: for(int i = 0; i < N; i++){ seznam[i] = rand() % (100); } #endif pthread_barrier_init(&barrier, NULL, T); izpisi_seznam(pSeznam); for (int i = 0; i < T; i++) { args[i].threadID = i; args[i].idxStart = i*((int) N / (int) T); if (i < T-1) args[i].iBlockSize = (int) N / (int) T; else args[i].iBlockSize = (int)((int)N / (int)T) + (int)((int)N % (int)T) - 1; pthread_create( &nit[i], NULL, pFunkcijaNiti, (void *) &args[i]); } for (int i = 0; i < T; i++) { pthread_join(nit[i], NULL); } pthread_barrier_destroy(&barrier); izpisi_seznam(pSeznam); }