Code:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <pthread.h>
#include <math.h>
#define MAX_THREADS 100
int Elmnt[10000];
int **tmp;
int m, n, Elmntsize, t, k, kAbs;
pthread_mutex_t mutex;
pthread_cond_t cond[MAX_THREADS];
/////////////////////////////////////
void Print () {
int i;
for(i=0; i<Elmntsize; i++){
if((i+1)%n == 0 && i != 0) {
printf("%d\n",Elmnt[i]);
}
else
printf("%d ",Elmnt[i]);
}
printf("\n");
}
////////////////////////////////
// read file //
int Readfile(char *fname){
FILE *f;
int i;
f = fopen(fname, "r");
if (f == NULL) {
fprintf(stderr, "file \"%s\" cannot open.\n", fname);
return -1;
}
fscanf(f,"%d %d",&m, &n);
Elmntsize = m*n;
for (i=0; i < Elmntsize; i++){
fscanf(f,"%d",&Elmnt[i]);
}
fclose(f);
return 0;
}
////////////////////////////////////////////////////////
// Find the average number of threads //
int avgCntRwTh(){
if(m == t) return 1;
if(t == 1) return m;
return floor((float)m/t+0.5);
}
/////////////////////////////////////////////////////////////////////////
// SHift of auxiliary tmp to new position(for right rotation) //
void tmpShiftRR(int id, int iL){
int i, preID;
if(id == 0) preID = t-1;
else preID = id-1;
for (i=0; i<kAbs; i++){
Elmnt[iL+i]= tmp[preID][kAbs-1-i];
}
}
----------------------------------------
// right rotation function //
----------------------------------------
void RotationR(int id, int iL, int iR){
int i;
for (i=0; i<kAbs; i++){
tmp[id][i] = Elmnt[iR-i];
}
for (i=iR-kAbs; i>=iL; i--){
Elmnt[i+kAbs] = Elmnt[i];
}
if(id == t-1) {
tmpShift(id, iL);
pthread_cond_signal(&cond[0]);
}
else {
pthread_cond_wait(&cond[id], &mutex);
tmpShiftRR(id, iL);
pthread_cond_signal(&cond[id+1]);
}
}
---------------------------------------
// Left rotation function //
---------------------------------------
void RotationL(int id, int iL, int iR){
int i;
for (i=0; i<kAbs; i++){ tmp[id][i] = Elmnt[iL+i]; }
for (i=iL; i<=iR; i++){ Elmnt[i] = Elmnt[i+kAbs]; }
if(id == t-1) {
tmpShiftRL(id, iR);
}
else {
pthread_cond_wait(&cond[id], &mutex);
tmpShiftRL(id, iR);
}
if(id != 0) pthread_cond_signal(&cond[id-1]);
}
--------------------
// rotate //
--------------------
void *rotate(void *threadid){
int id, cntR, pocR, konR, iL, iR;
id = (int)threadid;
printf("The working Thread is number: %d\n", id+1);
cntR = avgCntRwTh(); // To find out how many rows to be worked on average amount
pocR = (id)*cntR+1; // To provide rows where to begin rotation
if(id == t-1) {
cntR = m - (t-1)*cntR;
sleep(1);
} // For the Last thread of the remaining rows.
konR = pocR+cntR -1;
printf(" - This Threa is working with rows: %d-%d\n", pocR, konR);
//
iL = (pocR-1)*n; //First element of respective Thread
iR = konR*n -1; // Last element
//
pthread_mutex_lock(&mutex);
//
if(k < 0) rotationL(id, iL, iR); // left
else rotationR(id, iL, iR); // right
//
pthread_mutex_unlock(&mutex);
//
pthread_exit(NULL);
return NULL;
}
----------------------------------
// main //
-----------------------------------
int main(int argc, char *argv[])
{
char File;
int i, j, kN;
pthread_t ths[MAX_THREADS];
do {
// The reading of data from the file
do {
printf("\nType the name of the file (pro ukonceni programu: -1): ");
scanf("%s", &File);
if(atoi(&File) == -1) exit(0);
}
while(ReadFile(&File) != 0 );
printf("\nThe file was read:\n");
Print();
// The given number of Thread
do {
printf("Type total number of Threads(1-%d): ", m);
scanf("%d", &t);
if(t == -1) exit(0);
}
while(t < 1 || t > m);
if(t>MAX_THREADS) t = MAX_THREADS;
// The number of positions to be rotated
printf("Enter number of positions to be rotated: ");
scanf("%d", &k);
kAbs = abs(k);
if(kAbs > ElmntSize-1 && k >= 0) kAbs = kAbs %ElmntSize; // oriznuti kroku na velikost pole
if(kAbs > ElmntSize && k < 0) kAbs = kAbs %ElmntSize;
kN = kAbs /n; // pocet presahu na dalsi radek
kAbs = kAbs %n; // total number of positions during the first pass
// alokovani pomocneho 2d pole pro pomocne presuny
tmp = (int **)malloc(t*sizeof(int*));
for(i=0; i<t; i++)
tmp[i]=(int *)malloc(n*sizeof(int));
// Created Thread
pthread_mutex_init(&mutex, NULL);
for (j=0; j<=kN; j++){
if (kAbs == 0) { kAbs = n; continue; }
for(i=0; i<t; i++) {
if(pthread_cond_init (&cond[i], NULL)) {
printf("ERROR:During pthread_cond_init() - number %d\n)", i); exit(-1);
}
if(pthread_create(&ths[i], NULL, rotate, (void *) i)){
printf("ERROR: During thread_create() - number %d\n)", i); exit(-1);
}
usleep(500000);
}
for(i=0; i<t; i++){
pthread_join(ths[i], NULL);
pthread_cond_destroy(&cond[i]);
}
kAbs = n;
}
pthread_mutex_destroy(&mutex);
free(tmp);
// Rotated array to be printed
printf("\n\nRotated Array:\n");
Print();
printf("--- --- ---\n\n");
sleep(2);
} while (1);
return 0;
}