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/c21e31c5eff2a385824813215540bbfc to your computer and use it in GitHub Desktop.
Save MichaelStett/c21e31c5eff2a385824813215540bbfc to your computer and use it in GitHub Desktop.
SO Lab 11
// SO IS1 212A LAB05
// Michal Tymejczyk
// tm44537@zut.edu.pl
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Windows.h>
#include <time.h>
#include <stdbool.h>
HANDLE mutexHandler;
struct thread_args
{
int length;
float *args;
};
float sum = 0.0;
DWORD WINAPI create_thread(LPVOID data)
{
DWORD self = GetCurrentThreadId();
struct thread_args *args = (struct thread_args *)data;
fprintf(stdout, "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];
}
WaitForSingleObject(mutexHandler, INFINITE);
sum = sum + fSum;
ReleaseMutex(mutexHandler);
fprintf(stdout, "Thread #%ld sum=%f\n", self, fSum);
free(args->args);
free(args);
return 0;
}
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;
int n = strtol(argv[1], &narray, 10);
int w = strtol(argv[2], &warray, 10);
bool isValid = validate(argc, n, w, narray, warray);
if (!isValid)
{
return 1;
}
mutexHandler = CreateMutex(NULL, FALSE, NULL);
float t[n];
srand(time(NULL));
for (int i = 0; i < n; i++)
{
t[i] = 1000.0 * rand() / RAND_MAX;
}
DWORD *Thread_ids = malloc(w * sizeof(DWORD));
HANDLE *Thread_handles = malloc(w * sizeof(HANDLE));
const int sub_length = n / w;
const int reminder = n % w;
struct thread_args *temp_thread_args;
int sub_index = 0;
float *temp;
// Sum with threads
clock_t timer1;
timer1 = 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
{
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 // no reminder
{
temp_thread_args->length = sub_length;
}
temp_thread_args->args = temp;
Thread_handles[i] = CreateThread(NULL, 0, create_thread, temp_thread_args, 0, &Thread_ids[i]);
sub_index = sub_index + sub_length;
}
for (int i = 0; i < w; i++)
{
WaitForSingleObject(Thread_handles[i], INFINITE);
CloseHandle(Thread_handles[i]);
}
timer1 = clock() - timer1;
// Sum without threads
float sum2 = 0.0;
clock_t timer2;
timer2 = clock();
for (int i = 0; i < n; i++)
{
sum2 = sum2 + t[i];
}
timer2 = clock() - timer2;
fprintf(stdout, "Sum with threads: sum=%f, time=%fs\n", sum, (double)timer1 / CLOCKS_PER_SEC);
fprintf(stdout, "Sum without threads: sum=%f, time=%fs\n", sum2, (double)timer2 / CLOCKS_PER_SEC);
return 0;
}
// gcc lab11.c -o lab11.exe
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment