Removed submodules
This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* CS 361: Template project driver
|
||||
*
|
||||
* Name: Nicholas Tamassia
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <getopt.h>
|
||||
#include <inttypes.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "discrete.h"
|
||||
#include "pthread.h"
|
||||
|
||||
int cmdline (int, char **, size_t *, uint64_t **, uint64_t **, uint64_t **,
|
||||
size_t *);
|
||||
|
||||
void
|
||||
usage (void)
|
||||
{
|
||||
printf ("Usage: threads [options] (g:p:g2n ... )\n");
|
||||
printf (" Required arguments must be an array of g:p:g2n values\n");
|
||||
printf (" Options are:\n");
|
||||
printf (" -n N Create N concurrent threads\n");
|
||||
printf (" g:p:g2n is a colon-delimited list of 3 uint64_t values\n");
|
||||
printf (" g A group generator\n");
|
||||
printf (" p A prime number\n");
|
||||
printf (" g2n g^n mod p for some unknown n\n");
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
uint64_t *primes = NULL;
|
||||
uint64_t *gens = NULL;
|
||||
uint64_t *powers = NULL;
|
||||
size_t num_threads = 1;
|
||||
size_t num_args = 0;
|
||||
|
||||
if (cmdline (argc, argv, &num_args, &primes, &gens, &powers, &num_threads)
|
||||
< 0)
|
||||
{
|
||||
usage ();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (num_args < 1 || num_args > 20)
|
||||
{
|
||||
printf ("There must be between 1 and 20 arguments\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Unithreaded version to serve as a template
|
||||
if (num_threads == 1)
|
||||
{
|
||||
for (int i = 0; i < num_args; i++)
|
||||
{
|
||||
uint64_t result = discrete_log (powers[i], gens[i], primes[i]);
|
||||
printf ("Given g = %" PRId64 ", p = %" PRId64 ", g2n = %" PRId64
|
||||
" => n = %" PRId64 "\n",
|
||||
gens[i], primes[i], powers[i], result);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t *logs = calloc (num_args, sizeof (uint64_t));
|
||||
if (logs == NULL)
|
||||
{
|
||||
fprintf (stderr, "Failed to allocate logs array\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Adjust number of threads if there are fewer arguments than threads
|
||||
if (num_threads > num_args)
|
||||
num_threads = num_args;
|
||||
|
||||
size_t base
|
||||
= (num_args + num_threads - 1) / num_threads; // Ceiling division
|
||||
size_t rem = num_args % num_threads;
|
||||
|
||||
pthread_t *threads = calloc (num_threads, sizeof (pthread_t));
|
||||
struct time_args *targs
|
||||
= calloc (num_threads, sizeof (struct time_args));
|
||||
if (threads == NULL || targs == NULL)
|
||||
{
|
||||
free (logs);
|
||||
free (threads);
|
||||
free (targs);
|
||||
fprintf (stderr, "Failed to allocate thread structures\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
size_t created = 0;
|
||||
for (size_t t = 0; t < num_threads; t++)
|
||||
{
|
||||
size_t start = t * base;
|
||||
size_t count = (t + 1 == num_threads && rem > 0) ? rem : base;
|
||||
|
||||
targs[created].start_index = start;
|
||||
targs[created].number = count;
|
||||
targs[created].generators = gens;
|
||||
targs[created].primes = primes;
|
||||
targs[created].mod_powers = powers;
|
||||
targs[created].results = logs;
|
||||
|
||||
if (pthread_create (&threads[created], NULL, time_log_thread,
|
||||
(void *)&targs[created])
|
||||
!= 0)
|
||||
{
|
||||
for (size_t j = 0; j < created; j++)
|
||||
pthread_join (threads[j], NULL);
|
||||
free (logs);
|
||||
free (threads);
|
||||
free (targs);
|
||||
fprintf (stderr, "Failed to create worker thread\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
created++;
|
||||
}
|
||||
|
||||
for (size_t j = 0; j < created; j++)
|
||||
pthread_join (threads[j], NULL);
|
||||
|
||||
for (size_t i = 0; i < num_args; i++)
|
||||
{
|
||||
printf ("Given g = %lu, p = %lu, g2n = %lu => n = %lu\n", gens[i],
|
||||
primes[i], powers[i], logs[i]);
|
||||
}
|
||||
|
||||
free (logs);
|
||||
free (threads);
|
||||
free (targs);
|
||||
}
|
||||
|
||||
if (primes != NULL)
|
||||
free (primes);
|
||||
if (gens != NULL)
|
||||
free (gens);
|
||||
if (powers != NULL)
|
||||
free (powers);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
****************** DO NOT MODIFY FUNCTIONS IN THIS SECTION ******************
|
||||
*****************************************************************************/
|
||||
|
||||
int
|
||||
cmdline (int argc, char **argv, size_t *length, uint64_t **primes,
|
||||
uint64_t **gens, uint64_t **powers, size_t *num_threads)
|
||||
{
|
||||
int option;
|
||||
|
||||
while ((option = getopt (argc, argv, "n:h")) != -1)
|
||||
{
|
||||
switch (option)
|
||||
{
|
||||
case 'n':
|
||||
*num_threads = (size_t)strtol (optarg, NULL, 10);
|
||||
break;
|
||||
case 'h':
|
||||
return -1;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (optind == argc)
|
||||
return -1;
|
||||
*length = (size_t)(argc - optind);
|
||||
*primes = calloc (*length, sizeof (uint64_t));
|
||||
|
||||
size_t index;
|
||||
// These must both have g:p:g2n values
|
||||
*gens = calloc (*length, sizeof (uint64_t));
|
||||
*powers = calloc (*length, sizeof (uint64_t));
|
||||
for (index = optind; index < argc; index++)
|
||||
{
|
||||
char *token = strtok (argv[index], ":");
|
||||
uint64_t value = strtol (token, NULL, 10);
|
||||
(*gens)[index - optind] = value;
|
||||
token = strtok (NULL, ":");
|
||||
assert (token != NULL);
|
||||
value = strtol (token, NULL, 10);
|
||||
(*primes)[index - optind] = value;
|
||||
token = strtok (NULL, ":");
|
||||
assert (token != NULL);
|
||||
value = strtol (token, NULL, 10);
|
||||
(*powers)[index - optind] = value;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user