// Copyright 2021-2024 ECCI-UCR CC-BY 4.0
#define _DEFAULT_SOURCE
#include <assert.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
// my_random library ----------------------------------------------------------
// GCC values from https://en.wikipedia.org/wiki/Linear_congruential_generator
#define MODULUS 2147483648l
#define MULTIPLIER 1103515245l
#define INCREMENT 12345l
int my_actual = 0;
void my_seed(int seed) {
my_actual = seed;
}
int my_rand(int min, int max) {
const long next = (MULTIPLIER * my_actual + INCREMENT) % MODULUS;
my_actual = next;
return min + next % (max - min);
}
// tester program -------------------------------------------------------------
int count = 0;
int* numbers = NULL;
int min = 0;
int max = 0;
size_t thread_count = 0;
void* generate(void* data);
int main(int argc, char* argv[]) {
count = argc >= 2 ? atoi(argv[1]) : 1;
min = argc >= 3 ? atoi(argv[2]) : 0;
max = argc >= 4 ? atoi(argv[3]) : 100;
const int seed = argc >= 5 ? atoi(argv[4]) : clock() % MODULUS;
my_seed(seed);
numbers = (int*) calloc(count, sizeof(int));
assert(numbers);
thread_count = sysconf(_SC_NPROCESSORS_ONLN);
pthread_t threads[thread_count];
for (size_t index = 0; index < thread_count; ++index) {
pthread_create(&threads[index], NULL, generate, (void*)index);
}
for (size_t index = 0; index < thread_count; ++index) {
pthread_join(threads[index], NULL);
}
for (int index = 0; index < count; ++index) {
printf("%d\n", numbers[index]);
}
free(numbers);
return EXIT_SUCCESS;
}
void* generate(void* data) {
size_t rank = (size_t)data;
for (int index = rank; index < count; index += thread_count) {
numbers[index] = my_rand(min, max);
}
return NULL;
}