lab2 code.
This commit is contained in:
3
lab2/.gitignore
vendored
Normal file
3
lab2/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
numbers.txt
|
||||
sorted.txt
|
||||
build/
|
||||
14
lab2/Makefile
Normal file
14
lab2/Makefile
Normal file
@@ -0,0 +1,14 @@
|
||||
OUT_DIR := build
|
||||
OUT_BIN := $(OUT_DIR)/qsort
|
||||
|
||||
$(OUT_BIN): qsort.c
|
||||
mkdir -p $(OUT_DIR)
|
||||
gcc -pthread qsort.c -o $(OUT_BIN)
|
||||
|
||||
.PHONY: run
|
||||
run: $(OUT_BIN)
|
||||
./$(OUT_BIN)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf $(OUT_DIR)
|
||||
4
lab2/gen_num.sh
Normal file
4
lab2/gen_num.sh
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This is one-liner copied from chatgpt.
|
||||
shuf -i 0-1000000 -n 1000000 > numbers.txt
|
||||
125
lab2/qsort.c
Normal file
125
lab2/qsort.c
Normal file
@@ -0,0 +1,125 @@
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define NUM_LENGTH 1000000
|
||||
#define SINGLE_THREAD_SRTH 1000
|
||||
#define MAX_LINE_LENGTH 10
|
||||
|
||||
// The great thing about qsort is that by logic there is no data race!
|
||||
// We don't even need mutexes to protect data.
|
||||
|
||||
int *numbers;
|
||||
|
||||
struct ThreadArgs {
|
||||
int low;
|
||||
int high;
|
||||
};
|
||||
|
||||
void swap(int *a, int* b) {
|
||||
int temp = *b;
|
||||
*b = *a;
|
||||
*a = temp;
|
||||
}
|
||||
|
||||
// Returns the index of pivot in arr[].
|
||||
int partition(int low, int high) {
|
||||
int pivot = numbers[high]; // Pivot element
|
||||
int i = low - 1;
|
||||
|
||||
for (int j = low; j < high; j++) {
|
||||
if (numbers[j] < pivot) {
|
||||
i++;
|
||||
swap(&numbers[i], &numbers[j]);
|
||||
}
|
||||
}
|
||||
|
||||
swap(&numbers[i + 1], &numbers[high]);
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
// Used for list less than 1000 in length.
|
||||
void qsort_nothread(int low, int high) {
|
||||
if (low >= high) {
|
||||
return;
|
||||
}
|
||||
|
||||
int pivot_idx = partition(low, high);
|
||||
qsort_nothread(low, pivot_idx - 1);
|
||||
qsort_nothread(pivot_idx + 1, high);
|
||||
}
|
||||
|
||||
void *qsort_thread(void *arg) {
|
||||
struct ThreadArgs* args = (struct ThreadArgs*) arg;
|
||||
// printf("Low: %d, high: %d\n", args->low, args->high);
|
||||
if (args->high - args->low <= SINGLE_THREAD_SRTH) {
|
||||
qsort_nothread(args->low, args->high);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int pivot_idx = partition(args->low, args->high);
|
||||
struct ThreadArgs left_thd_arg = {
|
||||
.low = args->low,
|
||||
.high = pivot_idx - 1
|
||||
};
|
||||
struct ThreadArgs right_thd_arg = {
|
||||
.low = pivot_idx + 1,
|
||||
.high = args->high
|
||||
};
|
||||
pthread_t left_handle, right_handle;
|
||||
pthread_create(&left_handle, NULL, qsort_thread, (void *)&left_thd_arg);
|
||||
pthread_create(&right_handle, NULL, qsort_thread, (void *)&right_thd_arg);
|
||||
pthread_join(left_handle, NULL);
|
||||
pthread_join(right_handle, NULL);
|
||||
}
|
||||
|
||||
void do_qsort() {
|
||||
struct ThreadArgs arg = {
|
||||
.low = 0,
|
||||
.high = NUM_LENGTH - 1
|
||||
};
|
||||
qsort_thread(&arg);
|
||||
}
|
||||
|
||||
|
||||
int main() {
|
||||
printf("Start reading file...\n");
|
||||
numbers = malloc(sizeof(int) * NUM_LENGTH);
|
||||
if (!numbers) {
|
||||
printf("Failed to allocate memory");
|
||||
return 1;
|
||||
}
|
||||
|
||||
FILE *file = fopen("numbers.txt", "r");
|
||||
if (!file) {
|
||||
printf("Failed to open numbers file");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
char line[MAX_LINE_LENGTH];
|
||||
while (count < NUM_LENGTH && fgets(line, sizeof(line), file)) {
|
||||
// printf("Count: %d\n", count);
|
||||
sscanf(line, "%d", &numbers[count]);
|
||||
count++;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
printf("Start sorting...\n");
|
||||
do_qsort();
|
||||
printf("Done sorting, writing to file...\n");
|
||||
|
||||
file = fopen("sorted.txt", "w");
|
||||
if (!file) {
|
||||
printf("Filed to open sorted file");
|
||||
return 1;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
while (count < NUM_LENGTH) {
|
||||
fprintf(file, "%d\n", numbers[count]);
|
||||
count++;
|
||||
}
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user