- First, I would look at the signature of the standard function
qsort and provide the same interface for your sort function. I'd also rename it into bubble_sort since it's doing bubble sorting. Your function would then look like this:
void bubble_sort(void *ptr, size_t arrLen, size_t elem_size,
int (*comp)(const void *, const void *)) {
char *array = ptr; // to be able to do pointer arithmetic
for (size_t a = 0; a < arrLen - 1; a++) {
for (size_t b = a + 1; b < arrLen; b++) {
if (comp(array + a * elem_size, array + b * elem_size) > 0) {
swap(array + a * elem_size, array + b * elem_size, elem_size);
}
}
}
}
elem_size is the size of the elements you want to sort, which will be set to sizeof(int) later.
comp is a function taking two void* and returns an int where ...
< 0 means *a < *b
> 0 means *a > *b
== 0 means *a == *b
swap also takes the elem_size parameter to be able to swap objects of any size. Implemented, it could look like this:
void swap(void *a, void *b, size_t elem_size) {
char tmp[elem_size];
memcpy(tmp, a, elem_size);
memcpy(a, b, elem_size);
memcpy(b, tmp, elem_size);
}
Now, you can't start a thread by calling bubble_sort directly. A thread start routine only takes a single void* as an argument so we need some way of passing all the necessary arguments on. We can package them in a struct like this:
struct sort_thread_args {
pthread_t tid;
void *array;
size_t arrLen;
size_t elem_size;
int (*comp_func)(const void *, const void *);
};
void *sort_thread(void *arg) { // the thread start routine
struct sort_thread_args *ta = arg;
bubble_sort(ta->array, ta->arrLen, ta->elem_size, ta->comp_func);
return NULL;
}
As can be seen above, the struct contains all the necessary information to call bubble_sort + the thread id, which I've stored there for convenience only. It's not needed by the thread itself.
The above functions are type agnostic so you can use these to sort any contiguous array, either by calling bubble_sort directly or in a thread.
Since you'll be using this to sort arrays of int, we need a comparison function for ints which does what was described above:
int comp_int(const void *va, const void *vb) {
const int *a = va;
const int *b = vb;
if (*a < *b) return -1;
if (*a > *b) return 1;
return 0;
}
Then for sorting half the array in one thread and the other half in another thread, I suggest that you don't copy the contents of mainArray to new arrays. Just leave the content in mainArray and tell each thread where to start sorting and how many elements it should sort.
Example:
#define Size(x) (sizeof(x) / sizeof *(x))
int main() {
srand((unsigned)time(NULL));
puts("Program Initialized...");
int arrLen = 35; // just an example to show that it handes uneven amounts too
int mainArray[arrLen];
// Populate mainArray
for (size_t i = 0; i < Size(mainArray); i++) {
mainArray[i] = rand() % 100;
}
puts("Array created...");
// print the created array
for (size_t i = 0; i < Size(mainArray); ++i) printf("%2d ", mainArray[i]);
putchar('\n');
puts("Running sorting threads...");
struct sort_thread_args ta[2]; // 2 for 2 threads
for (size_t i = 0; i < Size(ta); ++i) {
// element index for where this thread should start sorting:
size_t base = i * Size(mainArray) / Size(ta);
// prepare the arguments for this thread:
ta[i] = (struct sort_thread_args) {
.array = mainArray + base, // points at the first element for this thread
.arrLen = (i + 1) * Size(mainArray) / Size(ta) - base,
.elem_size = sizeof(int),
.comp_func = comp_int // the comparison function we made above
};
// and start the thread:
pthread_create(&ta[i].tid, NULL, sort_thread, &ta[i]);
}
puts("Joining threads");
for (size_t i = 0; i < Size(ta); ++i) {
pthread_join(ta[i].tid, NULL);
}
puts("Result:");
for (size_t i = 0; i < Size(mainArray); ++i) printf("%2d ", mainArray[i]);
putchar('\n');
}
Demo
for(int a=0; a<arrLen-1; a++){, where does the value ofarrLencome from? What is that value? What does that indicate? Now - how long is the array data that you actually are passing? (Hint: what was the purpose of the code that createdfirstHalfandsecondHalf?) Final hint: try looking at how the standard library sort is implemented. Notice how it accepts a parameter to indicate the length of the array? Why do you suppose that is?void *sort(void *arg){, what do you expect that to mean? In particular, what does theargpart mean? Where the code saysif(array[b] < array[min_pos]){inside that function, what do you expect thearraypart to refer to? Why and how? Did you mean for it to refer to the data that is passed in? Is that namedarray? Do you see the problem?