forked from HariniMadhi/ParallelSort
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmerge.c
91 lines (71 loc) · 2.87 KB
/
merge.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <math.h>
#include <string.h>
#include <unistd.h>
#include "merge.h"
pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; //For synchronizing Output
int DEPTH = 8;
void gotoxy(int x, int y) //Function to move cursor to column x, row y, for formatting output
{
printf("%c[%d;%df", 0x1B, y, x);
}
void merge(int *start, int *mid, int *end, int depth, int threadspace, int flag) //Traditional merge function
{
int *res = malloc((end - start)*sizeof(*res)); //Auxillary memory, sum of the size of the two partitions to be merged
int *lhs = start, *rhs = mid, *dst = res;
while (lhs != mid && rhs != end)
*dst++ = (*lhs < *rhs) ? *lhs++ : *rhs++;
while (lhs != mid)
*dst++ = *lhs++;
// copy results
memcpy(start, res, (rhs - start) * sizeof *res);
free(res); //Free the auxillary space
if(flag) //Printing the starting and ending of the merged array, formatted
{
int i=threadspace*16, j=log(depth)/log(2) * 2 +DEPTH +4;
pthread_mutex_lock(&mtx);
gotoxy(i, j);
printf("%4d .. %4d", start[0], start[end-start -1]);
pthread_mutex_unlock(&mtx);
}
}
void merge_sort_mt(int *start, size_t len, int depth, int threadspace, int flag) //Function that divides, assigns thread, and merges
{
if (len < 2)
return;
if(flag) //Printing the starting and ending of the array that needs too be divided, formatted
{
int i=threadspace*16, j=DEPTH-2*(log(depth)/log(2)) + 2;
pthread_mutex_lock(&mtx);
gotoxy(i,j);
printf("%4d .. %4d", *start, *(start+len-1));
pthread_mutex_unlock(&mtx);
}
if(depth==1||len<4)
{ //If the Depth goes below 1, threads will not be created, and will be recursed instead
merge_sort_mt(start, len/2, 1, 0, 0); //flag is used to determine this
merge_sort_mt(start+len/2, len-len/2, 1, 0, 0);
}
else
{
struct parameter params = { start, len/2, depth/2, 2*threadspace , 1 }; //Creating parameter, to be sent as argument
pthread_t thrd;
// create our thread
pthread_create(&thrd, NULL, merge_sort_thread, ¶ms);
// recurse into our top-end parition
merge_sort_mt(start+len/2, len-len/2, depth/2, 2*threadspace +1, 1 );
// join on the launched thread ---- Synchronisation
pthread_join(thrd, NULL);
}
// merge the partitions.
merge(start, start+len/2, start+len, depth, threadspace, flag);
}
void *merge_sort_thread(void *pv)
{
struct parameter *params = (struct parameter *) pv; //Cast into parameter, to be sent into merge_sort_mt
merge_sort_mt(params->start, params->len, params->depth, params->threadspace, params->flag);
return pv;
}
void merge_sort(int *start, size_t len) //Initial call for the merge_sort_mt
{
merge_sort_mt(start, len, DEPTH, 0, 1); //This function abstracts other functions, and will be used in main.c
}