From 9b7527997bbd1da4d6ea66e75e0edcef1787bf30 Mon Sep 17 00:00:00 2001 From: Izak Baldacchino <83893457+Izak8@users.noreply.github.com> Date: Fri, 24 Oct 2025 14:16:39 +1030 Subject: [PATCH 1/8] chore: reorganise directory structure (#14) Includes a partially-authored README file. However, there are still some changes to make, as there are sections which we cannot fill out yet. This commit was accidentally authored under my university GitHub identity, woops. --------- Co-authored-by: Izak Baldacchino --- comp2002-os-mergesort/Makefile => Makefile | 0 README.md | 75 +++++++++++++++++++ comp2002-os-mergesort/README.template | 57 -------------- .../mergesort.c => mergesort.c | 0 .../mergesort.h => mergesort.h | 0 .../test-mergesort.c => test-mergesort.c | 0 6 files changed, 75 insertions(+), 57 deletions(-) rename comp2002-os-mergesort/Makefile => Makefile (100%) create mode 100644 README.md delete mode 100644 comp2002-os-mergesort/README.template rename comp2002-os-mergesort/mergesort.c => mergesort.c (100%) rename comp2002-os-mergesort/mergesort.h => mergesort.h (100%) rename comp2002-os-mergesort/test-mergesort.c => test-mergesort.c (100%) diff --git a/comp2002-os-mergesort/Makefile b/Makefile similarity index 100% rename from comp2002-os-mergesort/Makefile rename to Makefile diff --git a/README.md b/README.md new file mode 100644 index 0000000..02211c3 --- /dev/null +++ b/README.md @@ -0,0 +1,75 @@ +README.template + +## Project Number/Title + +* Authors: Izak Baldacchino (a1830164), Bunsarak Ann (a1827385), Matthew Edmonds-Wilson(a1850372) +* Group name: Assignment 3 Groups 190 + +## Overview + +This program benchmarks the performance of the parallel merge sort algorithm. +Given an array of random integers of size N, and a "level", it performs merge +sort; each time the array is partitioned, a new thread is spawned to perform +the recursive merge sort on the sub-array. This continues until the "level" +is exceeded. + +## Manifest + +Makefile -- the recipes which are used to compile the project. +README.md -- this file! +mergesort.c -- contains the source for the functions which need to be implemented. +mergesort.h -- contains the declarations for the functions and structs used. +test-mergesort.c -- contains the source for the program which runs the algorithm. + +## Building the project + +To build the project simply execute `make`. This assumes it is being built on a UNIX-like +system which features some rendition of the `make` utility. In fact, any system which is +POSIX-compliant shall be able to execute and run this makefile. + +From this point execute the built executable `./test-mergesort` and provide relevant arguments. + +## Features and usage + +To run the program use `./test-mergesort N level seed` where `N` refers to the size of the generated +array, `level` refers to the number of times the array is partitioned and sorted in parallel, and +`seed` is used as the seed for generating the random array; same seed = same array. + +TODO: write more perhaps? + +## Testing + +This section should detail how you tested your code. Simply stating "I ran +it a few times and it seems to work" is not sufficient. Your testing needs +to be detailed here. + + +TODO: figure out testing scheme. + +## Known Bugs + +List known bugs that you weren't able to fix (or ran out of time to fix). + +TODO: haven't made any bugs yet ... + +## Reflection and Self Assessment + +Discuss the issues you encountered during development and testing. What +problems did you have? What did you have to research and learn on your own? +What kinds of errors did you get? How did you fix them? + +What parts of the project did you find challenging? Is there anything that +finally "clicked" for you in the process of working on this project? How well +did the development and testing process go for you? + + +TODO: haven't finished yet ... + +## Sources Used + +If you used any sources outside of the textbook, you should list them here. +If you looked something up on stackoverflow.com or you use help from AI, and +fail to cite it in this section, it will be considered plagiarism and dealt +with accordingly. So be safe CITE! + +TODO: haven't used any sources yet ... diff --git a/comp2002-os-mergesort/README.template b/comp2002-os-mergesort/README.template deleted file mode 100644 index 38d5ffb..0000000 --- a/comp2002-os-mergesort/README.template +++ /dev/null @@ -1,57 +0,0 @@ -README.template - -## Project Number/Title - -* Authors: Your Name, and your group members’ names -* Group name: Your Group Name - -## Overview - -Concisely explain what the program does. If this exceeds a couple of -sentences, you're going too far. Generally, you should be pulling this -right from the project specification. We don't want you to just cut and -paste, but paraphrase what is stated in the project specification. - -## Manifest - -A listing of source files and other non-generated files, and a brief -(one-line) explanation of the purpose of each file. - -## Building the project - -This section should tell the user how to build your code. If you are -delivering a library, where does it need to be installed, or how do you use -it? Is this an executable, if so, how can a user get up to speed as fast as -possible? - -## Features and usage - -Summarise the main features of your program. It is also appropriate to -instruct the user how to use your program. - -## Testing - -This section should detail how you tested your code. Simply stating "I ran -it a few times and it seems to work" is not sufficient. Your testing needs -to be detailed here. - -## Known Bugs - -List known bugs that you weren't able to fix (or ran out of time to fix). - -## Reflection and Self Assessment - -Discuss the issues you encountered during development and testing. What -problems did you have? What did you have to research and learn on your own? -What kinds of errors did you get? How did you fix them? - -What parts of the project did you find challenging? Is there anything that -finally "clicked" for you in the process of working on this project? How well -did the development and testing process go for you? - -## Sources Used - -If you used any sources outside of the textbook, you should list them here. -If you looked something up on stackoverflow.com or you use help from AI, and -fail to cite it in this section, it will be considered plagiarism and dealt -with accordingly. So be safe CITE! diff --git a/comp2002-os-mergesort/mergesort.c b/mergesort.c similarity index 100% rename from comp2002-os-mergesort/mergesort.c rename to mergesort.c diff --git a/comp2002-os-mergesort/mergesort.h b/mergesort.h similarity index 100% rename from comp2002-os-mergesort/mergesort.h rename to mergesort.h diff --git a/comp2002-os-mergesort/test-mergesort.c b/test-mergesort.c similarity index 100% rename from comp2002-os-mergesort/test-mergesort.c rename to test-mergesort.c From 55eb1476934f058da0bc26ea1539cd11990b4903 Mon Sep 17 00:00:00 2001 From: Izak Baldacchino Date: Fri, 24 Oct 2025 16:11:25 +1030 Subject: [PATCH 2/8] feat: implement `merge` function Follows the basic mergesort algorithm provided by the video shown on the assignment description. Other sources accessed include: cppreference.com (for memcpy). --- mergesort.c | 60 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/mergesort.c b/mergesort.c index 3e8bf4e..16317c5 100644 --- a/mergesort.c +++ b/mergesort.c @@ -1,27 +1,67 @@ -/** - * This file implements parallel mergesort. - */ - #include -#include /* for memcpy */ -#include /* for malloc */ +#include +#include + #include "mergesort.h" /* this function will be called by mergesort() and also by parallel_mergesort(). */ -void merge(int leftstart, int leftend, int rightstart, int rightend){ + +/* merges two sub-arrays preserving order */ +void merge(int leftstart, int leftend, int rightstart, int rightend) { + + int leftindex = leftstart; + int rightindex = rightstart; + int index = leftstart; + + /* iterate through the main array A at two positions (leftstart and rightstart). + + for each index in B, insert the left or right element from A which is + of lesser value until either position is out of bounds + */ + + for(; (leftindex <= leftend) && (rightindex <= rightend); index++) { + /* choose left element from B if smaller */ + if(A[leftindex] <= A[rightindex]) { + B[index] = A[leftindex]; + leftindex++; + } + else /* choose right element */ { + B[index] = A[rightindex]; + rightindex++; + } + } + + /* loop terminates once either sub-array is out of bounds + + as such, remaining elements in either sub-array must be + copied to B + + either one of these copies may be a no-op (since only one + sub-array will have elements remaining at most) + */ + + int num_elements_to_copy_in_total = (rightend - leftstart) + 1; + int num_elements_to_copy_from_left = (leftend - leftindex) + 1; + int num_elements_to_copy_from_right = (rightend - rightindex) + 1; + + memcpy(&B[index], &A[leftindex], num_elements_to_copy_from_left); + memcpy(&B[index], &A[rightindex], num_elements_to_copy_from_right); + /* copy auxiliary array B, which is now sorted, back to A */ + memcpy(&A[leftstart], &B[leftstart], num_elements_to_copy_in_total); } /* this function will be called by parallel_mergesort() as its base case. */ -void my_mergesort(int left, int right){ +void my_mergesort(int left, int right) { + } /* this function will be called by the testing program. */ -void * parallel_mergesort(void *arg){ +void * parallel_mergesort(void* arg) { return NULL; } /* we build the argument for the parallel_mergesort function. */ -struct argument * buildArgs(int left, int right, int level){ +struct argument* buildArgs(int left, int right, int level) { return NULL; } From 28c05859b95f785b18dd8682493c9bd4195cf07d Mon Sep 17 00:00:00 2001 From: Izak Baldacchino Date: Fri, 24 Oct 2025 16:22:50 +1030 Subject: [PATCH 3/8] build: replace Makefile with a good, POSIX-compliant one Includes a Makefile based on a template I created for an old project (which can be found here: github.com/Izak8/gl). Build flags differ from original assignment; changed C standard from gnu89 to c11. gnu89 seems unecessarily limiting. --- Makefile | 56 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index fb7a828..5b9c13c 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,50 @@ -CC = gcc -CFLAGS = -Wall -Wpointer-arith -Wstrict-prototypes -std=gnu89 -fPIC -MMD -MP -lpthread +.POSIX: +.SUFFIXES: -all: test-mergesort +# Use the system's default C compiler +# was gnu89 reallyyyy necessary .... +# surely gradescope machines have a compiler which can do post Y2K C .... -#This builds an executable -test-mergesort: test-mergesort.o mergesort.o - $(CC) $(CFLAGS) -o $@ $? +CC = cc +CFLAGS = -Wall -Wpointer-arith -Wstrict-prototypes -std=c11 -fPIC -.PHONY: clean -clean: - /bin/rm -f *.o *.d test-mergesort +# Pathname of the pkg-config compatible utility +# (not using this for this assignment at all) +#PC = pkg-config + +# Instructions to create an LSP db -- default is clangd with compile_flags.txt +# e.g. To use bear you can set DB="bear -- make" which will create compile_commands.json +DB = echo $(LDFLAGS) $(CFLAGS) | tr ' ' '\n' > compile_flags.txt + +# Project Files +BIN=test-mergesort +OBJ=test-mergesort.o mergesort.o +SRC=$(OBJ:%.o=%.c) +DEP=$(OBJ:%.o=%.d) + +all: $(BIN) + +# Build binary from objects +$(BIN): $(OBJ) + $(CC) $(CFLAGS) -o $@ $(OBJ) $(LDFLAGS) + +# Suffix rules to create .o and .d files from sources +.SUFFIXES: .c .o +.c.o: + $(CC) $(CFLAGS) $(INC) -c $< + +.SUFFIXES: .c .d +.c.d: + $(CC) -MM $< -o $@ + +# Generate LSP database on each clean +db: + $(DB) + +clean: db + rm -fr $(BIN) + rm -fr $(OBJ) + rm -fr $(DEP) + +# For FreeBSD make use -include +-include $(DEP) From 41a616a571ef5aa88983e93c5b9a216aec85678d Mon Sep 17 00:00:00 2001 From: Izak Baldacchino Date: Fri, 24 Oct 2025 17:26:23 +1030 Subject: [PATCH 4/8] fix: pass number of BYTES to copy rather than number of elements --- mergesort.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mergesort.c b/mergesort.c index 16317c5..deccd14 100644 --- a/mergesort.c +++ b/mergesort.c @@ -40,14 +40,14 @@ void merge(int leftstart, int leftend, int rightstart, int rightend) { sub-array will have elements remaining at most) */ - int num_elements_to_copy_in_total = (rightend - leftstart) + 1; - int num_elements_to_copy_from_left = (leftend - leftindex) + 1; - int num_elements_to_copy_from_right = (rightend - rightindex) + 1; + int num_bytes_to_copy_in_total = ((rightend - leftstart) + 1) * sizeof(int); + int num_bytes_to_copy_from_left = ((leftend - leftindex) + 1) * sizeof(int); + int num_bytes_to_copy_from_right = ((rightend - rightindex) + 1) * sizeof(int); - memcpy(&B[index], &A[leftindex], num_elements_to_copy_from_left); - memcpy(&B[index], &A[rightindex], num_elements_to_copy_from_right); + memcpy(&B[index], &A[leftindex], num_bytes_to_copy_from_left); + memcpy(&B[index], &A[rightindex], num_bytes_to_copy_from_right); /* copy auxiliary array B, which is now sorted, back to A */ - memcpy(&A[leftstart], &B[leftstart], num_elements_to_copy_in_total); + memcpy(&A[leftstart], &B[leftstart], num_bytes_to_copy_in_total); } /* this function will be called by parallel_mergesort() as its base case. */ From 5f9ba27e18c4492ca040ff63e12ed3da3c38b120 Mon Sep 17 00:00:00 2001 From: Izak Baldacchino Date: Fri, 24 Oct 2025 17:39:16 +1030 Subject: [PATCH 5/8] test: add rudimentary unit test for `merge` function Just simply uses scopes to create predictable conditions. If the test executable isn't aborted by a failed assertion, then it is considered to pass. --- Makefile | 6 ++++ merge_test.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++ merge_test.make | 50 ++++++++++++++++++++++++++ 3 files changed, 151 insertions(+) create mode 100644 merge_test.c create mode 100644 merge_test.make diff --git a/Makefile b/Makefile index 5b9c13c..56a9055 100644 --- a/Makefile +++ b/Makefile @@ -37,6 +37,10 @@ $(BIN): $(OBJ) .c.d: $(CC) -MM $< -o $@ +# Unit tests +test: + make -f merge_test.make + # Generate LSP database on each clean db: $(DB) @@ -45,6 +49,8 @@ clean: db rm -fr $(BIN) rm -fr $(OBJ) rm -fr $(DEP) + + make -f merge_test.make clean # For FreeBSD make use -include -include $(DEP) diff --git a/merge_test.c b/merge_test.c new file mode 100644 index 0000000..0bcf6e6 --- /dev/null +++ b/merge_test.c @@ -0,0 +1,95 @@ +#include +#include +#include + +#include "mergesort.h" + +// global state is safe and good and never goes wrong and doesn't make testing difficult! +int* A; +int* B; + +void printA(size_t start, size_t end) { + printf("\nA "); + for(size_t i = start; i < end+1; i++) { + printf("%d ", A[i]); + } +} + +void printB(size_t start, size_t end) { + printf("\nB "); + for(size_t i = start; i < end+1; i++) { + printf("%d ", B[i]); + } +} + +/* unit test for merge function */ +int main(void) { + /* contrary to popular practice, malloc should not be casted + as void* is casted safely automatically */ + + /* first test: merge two halves of the full array */ + { + printf("Test 1: merge two havles of full array\n"); + A = malloc(10 * sizeof(int)); + B = malloc(10 * sizeof(int)); + + A[0] = 0; /* leftstart = 0*/ + A[1] = 1; + A[2] = 2; + A[3] = 3; + A[4] = 4; /* leftend = 4*/ + + A[5] = 3; /* rightstart = 5 */ + A[6] = 4; + A[7] = 5; + A[8] = 6; + A[9] = 7; /* rightend = 9 */ + + /* expected result is A=[0,1,2,3,3,4,4,5,6,7] */ + merge(0,4,5,9); + + assert(A[0] == 0); + assert(A[1] == 1); + assert(A[2] == 2); + assert(A[3] == 3); + assert(A[4] == 3); + assert(A[5] == 4); + assert(A[6] == 4); + assert(A[7] == 5); + assert(A[8] == 6); + assert(A[9] == 7); + + printf("Test 1: Passed\n"); + } + + + /* first test: merge two halves of the full array */ + { + printf("Test 2: merge two havles of sub-array\n"); + A = malloc(10 * sizeof(int)); + B = malloc(10 * sizeof(int)); + + A[0] = 5; + A[1] = 6; + A[2] = 7; + A[3] = 8; + A[4] = 9; + + A[5] = 10; /* leftstart = 5 */ + A[6] = 11; /* leftend = 6 */ + A[7] = 2; /* rightstart = 7 */ + A[8] = 3; + A[9] = 4; /* rightend = 9 */ + + /* expected result is A=[2,3,4,10,11] */ + merge(5,6,7,9); + + assert(A[5] == 2); + assert(A[6] == 3); + assert(A[7] == 4); + assert(A[8] == 10); + assert(A[9] == 11); + + printf("Test 2: Passed\n"); + } +} diff --git a/merge_test.make b/merge_test.make new file mode 100644 index 0000000..d4c3203 --- /dev/null +++ b/merge_test.make @@ -0,0 +1,50 @@ +.POSIX: +.SUFFIXES: + +# Use the system's default C compiler +# was gnu89 reallyyyy necessary .... +# surely gradescope machines have a compiler which can do post Y2K C .... + +CC = cc +CFLAGS = -Wall -Wpointer-arith -Wstrict-prototypes -std=c11 -fPIC + +# Pathname of the pkg-config compatible utility +# (not using this for this assignment at all) +#PC = pkg-config + +# Instructions to create an LSP db -- default is clangd with compile_flags.txt +# e.g. To use bear you can set DB="bear -- make" which will create compile_commands.json +DB = echo $(LDFLAGS) $(CFLAGS) | tr ' ' '\n' > compile_flags.txt + +# Project Files +BIN=merge_test.test +OBJ=merge_test.o mergesort.o +SRC=$(OBJ:%.o=%.c) +DEP=$(OBJ:%.o=%.d) + +all: $(BIN) + +# Build binary from objects +$(BIN): $(OBJ) + $(CC) $(CFLAGS) -o $@ $(OBJ) $(LDFLAGS) + +# Suffix rules to create .o and .d files from sources +.SUFFIXES: .c .o +.c.o: + $(CC) $(CFLAGS) $(INC) -c $< + +.SUFFIXES: .c .d +.c.d: + $(CC) -MM $< -o $@ + +# Generate LSP database on each clean +db: + $(DB) + +clean: db + rm -fr $(BIN) + rm -fr $(OBJ) + rm -fr $(DEP) + +# For FreeBSD make use -include +-include $(DEP) From 777e80930c6b9c00fb1a6ff5dd32a07790193144 Mon Sep 17 00:00:00 2001 From: Bunsarak Date: Mon, 27 Oct 2025 16:37:57 +1030 Subject: [PATCH 6/8] feat(merge): Only one remainder: after the loop, copy just the side that still has elements.Finish with a single memcpy from B[left..right] back to A had to remove include so tests build locally --- test-mergesort.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test-mergesort.c b/test-mergesort.c index b56ab5a..01038b5 100644 --- a/test-mergesort.c +++ b/test-mergesort.c @@ -3,8 +3,7 @@ #include #include /* for times system call */ #include /* for gettimeofday system call */ -#include -#include /* On MacOS you won't need this line */ +#include /* On MacOS you won't need this line */ #include "mergesort.h" /* the number of levels of threads, specified by the user */ From 9dddb6166555470499ce4b4460942b14bbc799db Mon Sep 17 00:00:00 2001 From: Bunsarak Date: Mon, 27 Oct 2025 16:49:30 +1030 Subject: [PATCH 7/8] feat(merge): Only one remainder: after the loop, copy just the side that still has elements.Finish with a single memcpy from B[left..right] back to A had to remove include so tests build locally --- mergesort.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/mergesort.c b/mergesort.c index deccd14..579f748 100644 --- a/mergesort.c +++ b/mergesort.c @@ -19,6 +19,7 @@ void merge(int leftstart, int leftend, int rightstart, int rightend) { of lesser value until either position is out of bounds */ + for(; (leftindex <= leftend) && (rightindex <= rightend); index++) { /* choose left element from B if smaller */ if(A[leftindex] <= A[rightindex]) { @@ -31,6 +32,19 @@ void merge(int leftstart, int leftend, int rightstart, int rightend) { } } + /* copy the remainder from whichever side still has elements */ + if (leftindex <= leftend) { + /* Left run has leftovers: copy them in one bulk transfer. */ + size_t n = (size_t)(leftend - leftindex + 1); + memcpy(&B[index], &A[leftindex], n * sizeof(int)); + index += (int)n; + } else if (rightindex <= rightend) { + /* Right run has leftovers: copy them in one bulk transfer. */ + size_t n = (size_t)(rightend - rightindex + 1); + memcpy(&B[index], &A[rightindex], n * sizeof(int)); + index += (int)n; + } + /* loop terminates once either sub-array is out of bounds as such, remaining elements in either sub-array must be @@ -40,14 +54,9 @@ void merge(int leftstart, int leftend, int rightstart, int rightend) { sub-array will have elements remaining at most) */ - int num_bytes_to_copy_in_total = ((rightend - leftstart) + 1) * sizeof(int); - int num_bytes_to_copy_from_left = ((leftend - leftindex) + 1) * sizeof(int); - int num_bytes_to_copy_from_right = ((rightend - rightindex) + 1) * sizeof(int); - - memcpy(&B[index], &A[leftindex], num_bytes_to_copy_from_left); - memcpy(&B[index], &A[rightindex], num_bytes_to_copy_from_right); - /* copy auxiliary array B, which is now sorted, back to A */ - memcpy(&A[leftstart], &B[leftstart], num_bytes_to_copy_in_total); + /* One bulk copy back into A. */ /* copy auxiliary array B, which is now sorted, back to A */ + size_t total = (size_t)(rightend - leftstart + 1); + memcpy(&A[leftstart], &B[leftstart], total * sizeof(int)); } /* this function will be called by parallel_mergesort() as its base case. */ From 0bd2a65eb62c5b140c84364a67c6b39a1eb08053 Mon Sep 17 00:00:00 2001 From: Bunsarak Date: Mon, 27 Oct 2025 17:29:47 +1030 Subject: [PATCH 8/8] Adds serial my_mergesort(left,right) used as the base case for parallel_mergesort, No threading changes yet; parallel_mergesort() remains a stub,fix(sort): correct my_mergesort base case (use left >= right) --- mergesort.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/mergesort.c b/mergesort.c index 579f748..53dbe03 100644 --- a/mergesort.c +++ b/mergesort.c @@ -19,7 +19,6 @@ void merge(int leftstart, int leftend, int rightstart, int rightend) { of lesser value until either position is out of bounds */ - for(; (leftindex <= leftend) && (rightindex <= rightend); index++) { /* choose left element from B if smaller */ if(A[leftindex] <= A[rightindex]) { @@ -32,19 +31,6 @@ void merge(int leftstart, int leftend, int rightstart, int rightend) { } } - /* copy the remainder from whichever side still has elements */ - if (leftindex <= leftend) { - /* Left run has leftovers: copy them in one bulk transfer. */ - size_t n = (size_t)(leftend - leftindex + 1); - memcpy(&B[index], &A[leftindex], n * sizeof(int)); - index += (int)n; - } else if (rightindex <= rightend) { - /* Right run has leftovers: copy them in one bulk transfer. */ - size_t n = (size_t)(rightend - rightindex + 1); - memcpy(&B[index], &A[rightindex], n * sizeof(int)); - index += (int)n; - } - /* loop terminates once either sub-array is out of bounds as such, remaining elements in either sub-array must be @@ -54,14 +40,26 @@ void merge(int leftstart, int leftend, int rightstart, int rightend) { sub-array will have elements remaining at most) */ - /* One bulk copy back into A. */ /* copy auxiliary array B, which is now sorted, back to A */ - size_t total = (size_t)(rightend - leftstart + 1); - memcpy(&A[leftstart], &B[leftstart], total * sizeof(int)); + int num_bytes_to_copy_in_total = ((rightend - leftstart) + 1) * sizeof(int); + int num_bytes_to_copy_from_left = ((leftend - leftindex) + 1) * sizeof(int); + int num_bytes_to_copy_from_right = ((rightend - rightindex) + 1) * sizeof(int); + + memcpy(&B[index], &A[leftindex], num_bytes_to_copy_from_left); + memcpy(&B[index], &A[rightindex], num_bytes_to_copy_from_right); + /* copy auxiliary array B, which is now sorted, back to A */ + memcpy(&A[leftstart], &B[leftstart], num_bytes_to_copy_in_total); } /* this function will be called by parallel_mergesort() as its base case. */ void my_mergesort(int left, int right) { + if (left >= right ) return; /* base case: array of size 0 or 1 is already sorted */ + + int mid = left + (right - left) / 2; // Split the range roughly in half + + my_mergesort(left, mid); /* sort the left half*/ + my_mergesort(mid + 1, right); /* sort the right half*/ + merge(left, mid, mid + 1, right); /* merge the two sorted halves */ } /* this function will be called by the testing program. */