Skip to content

Commit 212ebbd

Browse files
author
Josue Mosh
committed
Quicksort using threads
1 parent 04f6619 commit 212ebbd

File tree

4 files changed

+269
-6
lines changed

4 files changed

+269
-6
lines changed

Practices/P1/multi-thread/multi-thrd.c

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
/**
2-
* A pthread program illustrating how to create a simple
3-
* thread and some of the pthread API.
2+
* A pthread program illustrating how to create multiple
3+
* threads and some of the pthread API.
44
* This program implements the summation function where
55
* the summation operation is run in multiple threads.
66
*
77
* Most Unix/Linux/OS X users
88
* gcc multi-thrd.c thrd-posix.c -lpthread -lrt
99
*
10-
* @author Gagne, Galvin, Silberschatz
11-
* Operating System Concepts - Ninth Edition
12-
* Copyright John Wiley & Sons - 2013
10+
* @author Josue Mosiah Contreras Rocha
11+
* @file multi-thrd.c
12+
* @date 09/02/2020
1313
*/
1414

1515
// ------------------------------------------
@@ -104,7 +104,7 @@ int main(int argc, char *argv[]) {
104104
/**
105105
* The thread will begin control in this function.
106106
*
107-
* @param params Thread's attributes.
107+
* @param params Range for each thread.
108108
*/
109109
void *runner(void *params) {
110110
// Initial set up for the thread

Practices/P1/sort/quicksort.c

+179
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
/**
2+
* A pthread program illustrating how to create multiple
3+
* threads and some of the pthread API.
4+
* This program implements the quicksort algorithm where
5+
* the operation is run by multiples threads.
6+
*
7+
* Most Unix/Linux/OS X users
8+
* gcc quicksort.c thrd-posix.c -lpthread -lrt
9+
*
10+
* @author Josue Mosiah Contreras Rocha
11+
* @file quicksort.c
12+
* @date 09/02/2020
13+
*/
14+
15+
// ------------------------------------------
16+
// System and aplication specific headers
17+
// ------------------------------------------
18+
#include <pthread.h>
19+
#include <semaphore.h>
20+
#include <stdio.h>
21+
#include <stdlib.h>
22+
#include <time.h>
23+
24+
#include "thrd-posix.h"
25+
26+
// ------------------------------------------
27+
// Shared variables
28+
// ------------------------------------------
29+
static int *arr;
30+
static sem_t mutex;
31+
32+
// Prototypes
33+
void *runner( void *params );
34+
void swap( int *a, int *b );
35+
int partition( int lower, int upper );
36+
void quickSort( int lower, int upper );
37+
38+
/**
39+
* Main thread.
40+
*/
41+
int main(int argc, char *argv[]) {
42+
// Validate console arguments
43+
if ( argc != 2 ) {
44+
fprintf(stderr, "usage: a.out <integer value>\n");
45+
exit(EXIT_FAILURE);
46+
}
47+
48+
if ( atoi(argv[1]) < 0 ) {
49+
fprintf(stderr, "Argument %d must be non-negative\n", atoi(argv[1]));
50+
exit(EXIT_FAILURE);
51+
}
52+
53+
// Fill array with random numbers
54+
int arraySize = atoi(argv[1]);
55+
arr = malloc(sizeof(int) * arraySize);
56+
57+
srand(0); /* Seed */
58+
for( int i = 0; i < arraySize; ++i )
59+
arr[i] = rand() % 50;
60+
61+
printf("Unsorted array:\n");
62+
for ( int i = 0; i < arraySize; ++i )
63+
printf("%d%s", arr[i], i == (arraySize - 1) ? "\n\n" : " ");
64+
65+
66+
// Initialize threads
67+
const unsigned int THREADS = 1;
68+
// const unsigned int THREADS = getThreads(); // This approach is faulty
69+
70+
pthread_t *tid = (pthread_t *) malloc(sizeof(pthread_t) * THREADS);
71+
pthread_attr_t attr;
72+
73+
// Sort's range for each thread
74+
int rangeSize = arraySize / THREADS;
75+
int range[THREADS * 2];
76+
77+
int first = 0, second = rangeSize - 1;
78+
for( int i = 0; i < THREADS; ++i ) {
79+
// Fill
80+
range[i * 2] = first;
81+
range[(i * 2) + 1] = i == (THREADS - 1) ? arraySize - 1 : second;
82+
83+
// Update
84+
first += rangeSize;
85+
second += rangeSize;
86+
}
87+
88+
// Create threads
89+
sem_init(&mutex, 0, 1); /* Create semaphore */
90+
pthread_attr_init(&attr); /* Default attributes */
91+
92+
for( int i = 0; i < THREADS; ++i ) {
93+
pthread_create(&tid[i], &attr, runner, &range[i * 2]);
94+
pthread_join(tid[i], NULL); /* Wait for threads */
95+
}
96+
97+
// Results
98+
sem_destroy(&mutex); /* Destroy semaphore */
99+
printf("Sorted array:\n");
100+
for ( int i = 0; i < arraySize; ++i )
101+
printf("%d%c", arr[i], i == (arraySize - 1) ? '\n' : ' ');
102+
}
103+
104+
/**
105+
* The thread will begin control in this function.
106+
*
107+
* @param params Range for each thread.
108+
*/
109+
void *runner(void *params) {
110+
// Initial set up for the thread
111+
int *param = (int *)params;
112+
int lower = param[0], upper = param[1];
113+
114+
// Operations
115+
quickSort(lower, upper);
116+
pthread_exit(0);
117+
}
118+
119+
/**
120+
* Swap two elements at memory level.
121+
*
122+
* @param a First element.
123+
* @param b Second element.
124+
*/
125+
void swap( int *a, int *b ) {
126+
int t = *a;
127+
*a = *b;
128+
*b = t;
129+
}
130+
131+
/**
132+
* Sorts a file-scope array with the quicksort algorithm.
133+
*
134+
* @param lower Starting index.
135+
* @param upper Ending index.
136+
* @return Position of the first element in the next partition.
137+
*/
138+
int partition( int lower, int upper ) {
139+
// Initialize
140+
int pivot = arr[upper];
141+
int i = lower - 1; // Index of smaller element
142+
143+
// Operations
144+
for ( int j = lower; j <= upper - 1; ++j ) {
145+
if ( arr[j] < pivot ) {
146+
// Increment index of smaller element
147+
i++;
148+
149+
// Critical section
150+
sem_wait(&mutex);
151+
swap(&arr[i], &arr[j]);
152+
sem_post(&mutex);
153+
}
154+
}
155+
156+
// Critical section
157+
sem_wait(&mutex);
158+
swap(&arr[i + 1], &arr[upper]);
159+
sem_post(&mutex);
160+
161+
return (i + 1);
162+
}
163+
164+
/**
165+
* Implements the QuickSort algorithm.
166+
*
167+
* @param lower Starting index.
168+
* @param upper Ending index.
169+
*/
170+
void quickSort( int lower, int upper ) {
171+
if ( lower < upper ) {
172+
// Partitioning index
173+
int pi = partition(lower, upper);
174+
175+
// Sort elements before and after partition
176+
quickSort(lower, pi - 1);
177+
quickSort(pi + 1, upper);
178+
}
179+
}

Practices/P1/sort/thrd-posix.c

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// See compressor.h for more info
2+
// Author: Josue Mosiah Contreras Rocha
3+
// File: thrd-posix.c
4+
// Date: 05/02/20
5+
6+
// ------------------------------------------
7+
// System and aplication specific headers
8+
// ------------------------------------------
9+
#include <stdlib.h>
10+
#include "thrd-posix.h"
11+
12+
13+
// -----------------------------
14+
// Public elements
15+
// -----------------------------
16+
17+
// Public functions
18+
19+
/**
20+
* Get the number of cores the system has.
21+
*
22+
* @return Number of cores.
23+
*/
24+
unsigned int getCores( void ) {
25+
unsigned int eax = 11, ebx = 0, ecx = 1, edx = 0;
26+
asm volatile("cpuid"
27+
: "=a"(eax),
28+
"=b"(ebx),
29+
"=c"(ecx),
30+
"=d"(edx)
31+
: "0"(eax),"2"(ecx)
32+
:);
33+
34+
return eax;
35+
}
36+
37+
/**
38+
* Get the number of threads the system has.
39+
*
40+
* @return Number of threads.
41+
*/
42+
unsigned int getThreads( void ) {
43+
unsigned int eax = 11, ebx = 0, ecx = 1, edx = 0;
44+
asm volatile("cpuid"
45+
: "=a"(eax),
46+
"=b"(ebx),
47+
"=c"(ecx),
48+
"=d"(edx)
49+
: "0"(eax),"2"(ecx)
50+
:);
51+
52+
return ebx;
53+
}
54+
55+
/**
56+
* Get the current thread in use.
57+
*
58+
* @return Actual in use.
59+
*/
60+
unsigned int getCurrentThread( void ) {
61+
unsigned int eax = 11, ebx = 0, ecx = 1, edx = 0;
62+
asm volatile("cpuid"
63+
: "=a"(eax),
64+
"=b"(ebx),
65+
"=c"(ecx),
66+
"=d"(edx)
67+
: "0"(eax),"2"(ecx)
68+
:);
69+
70+
return edx;
71+
}

Practices/P1/sort/thrd-posix.h

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// A set of functions that retrieves some OS parameters.
2+
// Author: Josue Mosiah Contreras Rocha
3+
// File: thrd-posix.h
4+
// Date: 05/02/2020
5+
6+
// -----------------------------
7+
// Public interface
8+
// -----------------------------
9+
10+
// Functions
11+
unsigned int getCores( void );
12+
unsigned int getThreads( void );
13+
unsigned int getCurrentThread( void );

0 commit comments

Comments
 (0)