Skip to content

Instantly share code, notes, and snippets.

@MichaelStett
Created January 22, 2020 20:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MichaelStett/c8c3cb3d6b61c9c57587e0bad076c645 to your computer and use it in GitHub Desktop.
Save MichaelStett/c8c3cb3d6b61c9c57587e0bad076c645 to your computer and use it in GitHub Desktop.
SO Lab 10
// SO IS1 212A LAB04
// Michal Tymejczyk
// tm44537@zut.edu.pl
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <stdbool.h>
pthread_mutex_t iMutex = PTHREAD_MUTEX_INITIALIZER;
struct pthread_args
{
int length;
float *args;
};
float sum = 0;
void *create_thread(void *data)
{
pthread_t self = pthread_self();
struct pthread_args *args = (struct pthread_args *)data;
printf("Thread #%ld size=%d\n", self, args->length);
float fSum = 0.0;
for (int i = 0; i < args->length; i++)
{
fSum = fSum + args->args[i];
}
pthread_mutex_lock(&iMutex);
sum = sum + fSum;
pthread_mutex_unlock(&iMutex);
printf("Thread #%ld sum=%f\n", self, fSum);
free(args->args);
free(args);
return (void *)&sum;
}
bool validate(int args_count, int n, int w, char* narray, char* warray)
{
if (args_count != 3)
{
fprintf(stderr, "%s\n", "Error: Args count.");
return false;
}
if ((n <= 0) || (n >= 1000000))
{
fprintf(stderr, "%s\n", "Error: Args n <= 0 or n >= 1000000");
return false;
}
if ((w <= 0) || (w >= n))
{
fprintf(stderr, "%s\n", "Error: Args are w <= 0 or w >= n!");
return false;
}
if (*narray != '\0' || *warray != '\0')
{
fprintf(stderr, "%s\n", "Error: Args aren't integers!");
return false;
}
return true;
}
int main(int argc, char *argv[])
{
char *narray;
char *warray;
const int n = strtol(argv[1], &narray, 10);
const int w = strtol(argv[2], &warray, 10);
bool isValid = validate(argc, n, w, narray, warray);
if (!isValid) {
return 1;
}
float t[n];
srand(time(NULL));
for (int i = 0; i < n; i++)
{
t[i] = 1000.0 * rand() / RAND_MAX;
}
pthread_t thread_ids[w];
const int sub_length = n / w;
const int reminder = n % w;
int sub_index = 0;
float *temp;
struct pthread_args *temp_thread_args;
// Sum with threads
float sum = 0.0;
clock_t start = clock();
for (int i = 0; i < w; i++)
{
if ((i == (w - 1)) && (reminder != 0))
{
temp = malloc((sub_length + reminder) * sizeof(t[0]));
memcpy(temp, &t[sub_index], (sub_length + reminder) * sizeof(t[0]));
}
else // no reminder
{
temp = malloc(sub_length * sizeof(t[0]));
memcpy(temp, &t[sub_index], sub_length * sizeof(t[0]));
}
temp_thread_args = malloc(sizeof(*temp_thread_args));
if ((i == (w - 1)) && (reminder != 0))
{
temp_thread_args->length = sub_length + reminder;
}
else
{
temp_thread_args->length = sub_length;
}
temp_thread_args->args = temp;
pthread_create(thread_ids + i, NULL, create_thread, temp_thread_args);
sub_index = sub_index + sub_length;
}
long x = 0;
for (int i = 0; i < w; i++)
{
pthread_join(thread_ids[i], (void *)&x);
}
clock_t stop = clock();
// Sum without threads
int sum2 = 0;
clock_t start2 = clock();
for (int i = 0; i < n; i++)
{
sum2 = sum2 + t[i];
}
clock_t stop2 = clock();
float time_1 = (stop - start) / (float)CLOCKS_PER_SEC;
float time_2 = (stop2 - start2) / (float)CLOCKS_PER_SEC;
printf("Sum with threads: sum=%f, time=%.3fsec\n", sum, time_1);
printf("Sum without threads: sum=%f, time=%.3fsec\n", sum2, time_2);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment