From ee1c25488a94872afc64509554197b149dc55c0f Mon Sep 17 00:00:00 2001 From: Fabio Scotto di Santolo Date: Fri, 30 Aug 2024 15:55:28 +0200 Subject: [PATCH] Added exercises on thread arguments --- threads/ex421.c | 101 ++++++++++++++++++++++++++++++++++++++++++ threads/ex424.c | 56 +++++++++++++++++++++++ threads/ex426.c | 57 ++++++++++++++++++++++++ threads/project2.c | 108 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 322 insertions(+) create mode 100644 threads/ex421.c create mode 100644 threads/ex424.c create mode 100644 threads/ex426.c create mode 100644 threads/project2.c diff --git a/threads/ex421.c b/threads/ex421.c new file mode 100644 index 0000000..328934c --- /dev/null +++ b/threads/ex421.c @@ -0,0 +1,101 @@ +#include +#include +#include +#include + +#define OPERATIONS 3 +#define MIN(a, b) a > b ? b : a +#define MAX(a, b) a < b ? b : a + +void *min(void *); +void *avg(void *); +void *max(void *); + +typedef void *(*pthread_fn_t)(void *); + +typedef struct __THREAD_DATA__ { + int *numbers; + int size; +} thread_data_t; + +int minimum = INT_MAX; +int maximum = INT_MIN; +int average = 0; + +int main(int argc, char *argv[]) { + if (argc < 2) { + perror("Usage: statistic NUMBERS...\n"); + exit(EXIT_FAILURE); + } + + const int size = argc - 1; + int *numbers = (int *)calloc(size, sizeof(int)); + for (int i = 1; i < argc; i++) { + numbers[i - 1] = atoi(argv[i]); + } + + const thread_data_t tdata = {.numbers = numbers, .size = size}; + const pthread_fn_t ops[OPERATIONS] = {min, max, avg}; + + pthread_attr_t attr; + pthread_t threads[OPERATIONS]; + pthread_attr_init(&attr); + for (size_t i = 0; i < OPERATIONS; i++) { + pthread_create(&threads[i], &attr, ops[i], (void *)&tdata); + } + + for (int i = 0; i < OPERATIONS; i++) { + pthread_join(threads[i], NULL); + } + + printf("Summary:\n"); + printf("The average value is %d\n", average); + printf("The minimum value is %d\n", minimum); + printf("The maximum value is %d\n", maximum); + + free(numbers); + numbers = NULL; + + return EXIT_SUCCESS; +} + +void *min(void *args) { + const thread_data_t *tdata = (thread_data_t *)args; + const int *numbers = tdata->numbers; + const int size = tdata->size; + + for (int i = 0; i < size; i++) { + minimum = MIN(minimum, numbers[i]); + } + + pthread_exit(0); +} + +void *max(void *args) { + const thread_data_t *tdata = (thread_data_t *)args; + const int *numbers = tdata->numbers; + const int size = tdata->size; + + for (int i = 0; i < size; i++) { + maximum = MAX(maximum, numbers[i]); + } + + pthread_exit(0); +} + +int sum(const int *values, const int n) { + int sum = 0; + for (int i = 0; i < n; i++) { + sum += values[i]; + } + return sum; +} + +void *avg(void *args) { + const thread_data_t *tdata = (thread_data_t *)args; + const int *numbers = tdata->numbers; + const int size = tdata->size; + const int total = sum(numbers, size); + average = total / size; + pthread_exit(0); +} diff --git a/threads/ex424.c b/threads/ex424.c new file mode 100644 index 0000000..8083eb2 --- /dev/null +++ b/threads/ex424.c @@ -0,0 +1,56 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include + +bool prime(int n); +void *primes(void *); + +const int thread_err = 1; + +int main(int argc, char *argv[]) { + if (argc < 2) { + perror("Usage: prime NUMBER\n"); + exit(EXIT_SUCCESS); + } + + const int n = atoi(argv[1]); + + pthread_attr_t attr; + pthread_t thread; + pthread_attr_init(&attr); + pthread_create(&thread, &attr, primes, (void *)&n); + pthread_join(thread, NULL); + + return EXIT_SUCCESS; +} + +void *primes(void *args) { + printf("Thread %d calculate primes number\n", gettid()); + const int *n = (int *)args; + + if (*n <= 1) { + perror("Is not possible calculate prime numbers for number less or equal " + "than 1\n"); + pthread_exit((void *)&thread_err); + } + + for (int i = 2; i <= *n; i++) { + if (prime(i)) { + printf("%d ", i); + } + } + printf("\n"); + pthread_exit(0); +} + +bool prime(int n) { + for (int i = 2; i < n; i++) { + if (n % i == 0) { + return false; + } + } + return true; +} diff --git a/threads/ex426.c b/threads/ex426.c new file mode 100644 index 0000000..6ce3724 --- /dev/null +++ b/threads/ex426.c @@ -0,0 +1,57 @@ +#include +#include +#include + +typedef unsigned long long int bigint_t; + +void *fibonacci(void *); + +bigint_t *numbers; + +int main(int argc, char *argv[]) { + if (argc < 2) { + perror("USAGE: fibonacci NUMBER\n"); + exit(EXIT_FAILURE); + } + + const int n = atoi(argv[1]); + numbers = (bigint_t *)calloc(n, sizeof(bigint_t)); + + pthread_attr_t attr; + pthread_t thread; + pthread_attr_init(&attr); + pthread_create(&thread, &attr, fibonacci, (void *)&n); + pthread_join(thread, NULL); + + printf("Fibonacci of %d:\n", n); + for (int i = 0; i < n; i++) { + printf("%llu ", numbers[i]); + } + printf("\n"); + + free(numbers); + numbers = NULL; + + return EXIT_SUCCESS; +} + +void *fibonacci(void *args) { + const int *n = (int *)args; + bigint_t first = 0, second = 1; + + if (*n >= 1) { + numbers[0] = first; + } + if (*n >= 2) { + numbers[1] = second; + } + + for (int i = 2; i < *n; i++) { + const bigint_t third = first + second; + first = second; + second = third; + numbers[i] = third; + } + + pthread_exit(0); +} diff --git a/threads/project2.c b/threads/project2.c new file mode 100644 index 0000000..3cfdce6 --- /dev/null +++ b/threads/project2.c @@ -0,0 +1,108 @@ +#include +#include +#include +#include + +#define ROUNDUP(a, b) (a + b - 1) / b + +void *sort(void *); +void *merge(void *); + +typedef struct __THREAD_DATA__ { + int *array; + int size; +} thread_data_t; + +typedef struct __MERGE_DATA__ { + thread_data_t tdata1; + thread_data_t tdata2; +} merge_data_t; + +int *original_array; +int *sorted_array; + +int main(int argc, char *argv[]) { + if (argc < 2) { + perror("USAGE: sortt NUMBERS...\n"); + exit(EXIT_FAILURE); + } + + const int size = argc - 1; + original_array = (int *)calloc(size, sizeof(int)); + for (int i = 1; i < argc; i++) { + original_array[i - 1] = atoi(argv[i]); + } + + int size1 = ROUNDUP(size, 2); + int size2 = size - size1; + int *slice1 = &original_array[0]; + int *slice2 = &original_array[size2 + 1]; + const thread_data_t tdata1 = {.array = slice1, .size = size1}; + const thread_data_t tdata2 = {.array = slice2, .size = size2}; + + pthread_attr_t attr; + pthread_t threads[3]; + pthread_attr_init(&attr); + pthread_create(&threads[0], &attr, sort, (void *)&tdata1); + pthread_create(&threads[1], &attr, sort, (void *)&tdata2); + for (int i = 0; i < 2; i++) { + pthread_join(threads[i], NULL); + } + + sorted_array = (int *)calloc(size, sizeof(int)); + merge_data_t mdata = {.tdata1 = tdata1, .tdata2 = tdata2}; + pthread_create(&threads[2], &attr, merge, (void *)&mdata); + pthread_join(threads[2], NULL); + + for (int i = 0; i < size; i++) { + printf("%d ", sorted_array[i]); + } + printf("\n"); + + free(original_array); + original_array = NULL; + + free(sorted_array); + sorted_array = NULL; + + return EXIT_SUCCESS; +} + +void swap(int *array, int a, int b) { + int tmp = array[a]; + array[a] = array[b]; + array[b] = tmp; +} + +void selection_sort(int *arr, int size) { + for (int i = 0; i < size - 1; i++) { + int min_idx = i; + for (int j = i + 1; j < size; j++) { + if (arr[j] < arr[min_idx]) { + min_idx = j; + } + } + swap(arr, min_idx, i); + } +} + +void *sort(void *args) { + const thread_data_t *tdata = (thread_data_t *)args; + selection_sort(tdata->array, tdata->size); + pthread_exit(0); +} + +void *merge(void *args) { + const merge_data_t *mdata = (merge_data_t *)args; + const thread_data_t tdata1 = mdata->tdata1; + const thread_data_t tdata2 = mdata->tdata2; + const int size = tdata1.size + tdata2.size; + for (int i = 0; i < tdata1.size; i++) { + sorted_array[i] = tdata1.array[i]; + } + for (int i = tdata1.size; i < size; i++) { + sorted_array[i] = tdata2.array[i - tdata1.size]; + } + selection_sort(sorted_array, size); + pthread_exit(0); +}