// Copyright 2021-2024 ECCI-UCR CC-BY 4.0 #define _DEFAULT_SOURCE #include #include #include #include #include #include #include // 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; pthread_mutex_t my_mutex; void my_seed(int seed) { my_actual = seed; } int my_rand(int min, int max) { pthread_mutex_lock(&my_mutex); const long next = (MULTIPLIER * my_actual + INCREMENT) % MODULUS; // for (size_t index = 0; index < 100000000; ++index) { my_actual = next; // } pthread_mutex_unlock(&my_mutex); return min + next % (max - min); } // tester program ------------------------------------------------------------- int count = 0; int* numbers = NULL; int min = 0; int max = 0; size_t thread_count = 1; void* generate(void* data); void signal_handler(int signal_id); int main(int argc, char* argv[]) { signal(SIGINT, signal_handler); 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; pthread_mutex_init(&my_mutex, NULL); my_seed(seed); numbers = (int*) calloc(count, sizeof(int)); assert(numbers); #ifdef SERIAL generate((void*)0); #else 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); } #endif for (int index = 0; index < count; ++index) { printf("%d\n", numbers[index]); } pthread_mutex_destroy(&my_mutex); free(numbers); return EXIT_SUCCESS; } void* generate(void* data) { const size_t rank = (size_t)data; for (int index = rank; index < count; index += thread_count) { numbers[index] = my_rand(min, max); } return NULL; } void signal_handler(int signal_id) { fprintf(stderr, "signal_hadler(%d): my_actual=%d generated=%d\n" , signal_id, my_actual, my_rand(0, 100)); }