Files
OS/lab2/qsort.c
2025-04-20 21:11:57 +08:00

125 lines
2.9 KiB
C

#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;
}