diff --git a/main.c b/main.c index b584942..d3be57d 100644 --- a/main.c +++ b/main.c @@ -111,13 +111,12 @@ static void print_arg_error(const char *arg); static void print_help_and_exit(void); static void print_version_and_exit(void); static void print_info_and_exit(void); -static unsigned long find_gcf(unsigned long *nums, size_t len); -static unsigned long *find_prime_factors(unsigned long n, size_t *out_len); static void initialize_modules(void); +static unsigned long gcd(unsigned long n1, unsigned long n2); +static unsigned long find_module_refresh_time(void); static void set_refresh_time(void); static void signal_handler(int signum); static void setup_signals(void); -static unsigned long find_module_refresh_gcf(void); static unsigned long timespec_to_miliseconds(struct timespec *ts); static void miliseconds_to_timespec(unsigned long ms, struct timespec *out_ts); static void do_initial_refresh(void); @@ -431,102 +430,6 @@ static void print_info_and_exit(void) { qtb_exit(); } -static unsigned long find_gcf(unsigned long *nums, size_t len) { - if (len == 0) { /* gcf(0) = 0 */ - return 0; - } else if (len == 1) { /* gcf(n) = n */ - return nums[0]; - } - /* calculate all prime factors */ - unsigned long **prime_factors = NULL; - size_t prime_factors_length = 0; - size_t i; - for (i = 0; i < len; ++i) { - unsigned long *i_prime_factors = find_prime_factors(nums[i], NULL); - prime_factors = qtb_realloc(prime_factors, sizeof(unsigned long *) * - ++prime_factors_length); - prime_factors[prime_factors_length - 1] = i_prime_factors; - } - /* find which calculated prime factors are common to all inputs */ - unsigned long *common_factors = NULL; - size_t common_factors_length = 0; - unsigned long *j; - /* loop though each factor in prime_factors[0] */ - for (j = prime_factors[0]; *j != 0; ++j) { - /* loop though every set of factors except prime_factors[0] */ - /* size_t i; */ - for (i = 1; i < prime_factors_length; ++i) { - unsigned long *i_prime_factors; - for (i_prime_factors = prime_factors[i]; *i_prime_factors != 0; - ++i_prime_factors) { - if (*i_prime_factors == *j) { - *i_prime_factors = 4; /* remove the factor (by setting it to - a composite number) */ - goto found_factor; - } - } - /* the factor was not found, therefore we can't add it */ - goto dont_add; - /* we found the factor, check the next set of factors */ - found_factor: - continue; - } - /* the factor was a common factor, add it */ - common_factors = qtb_realloc( - common_factors, sizeof(unsigned long) * ++common_factors_length); - common_factors[common_factors_length - 1] = *j; - /* the factor was not a common factor */ - dont_add: - continue; - } - /* qtb_free sets of factors */ - /* size_t i; */ - for (i = 0; i < prime_factors_length; ++i) { - qtb_free(prime_factors[i]); - } - qtb_free(prime_factors); - /* finally, calculate the gcf */ - unsigned long gcf = 1; - /* size_t i; */ - for (i = 0; i < common_factors_length; ++i) { - gcf *= common_factors[i]; - } - qtb_free(common_factors); - return gcf; -} - -/* return value will be 0 terminated. if out_len is not NULL, - it's value will be set to the number of primes found (length of return value - - 1) */ -static unsigned long *find_prime_factors(unsigned long n, size_t *out_len) { - unsigned long *out_arr = NULL; - size_t arr_len = 0; - while (n % 2 == 0) { - out_arr = qtb_realloc(out_arr, sizeof(unsigned long) * ++arr_len); - out_arr[arr_len - 1] = 2; - n /= 2; - } - unsigned long i; - for (i = 3; i <= sqrtl(n); i += 2) { - while (n % i == 0) { - out_arr = - qtb_realloc(out_arr, sizeof(unsigned long) * ++arr_len); - out_arr[arr_len - 1] = i; - n /= i; - } - } - if (n > 2) { - out_arr = qtb_realloc(out_arr, sizeof(unsigned long) * ++arr_len); - out_arr[arr_len - 1] = n; - } - out_arr = qtb_realloc(out_arr, sizeof(unsigned long) * arr_len); - out_arr[arr_len] = 0; - if (out_len) { - *out_len = arr_len; - } - return out_arr; -} - static void initialize_modules() { int has_error = FALSE; size_t i; @@ -552,11 +455,42 @@ static void initialize_modules() { } } +unsigned long gcd(unsigned long n1, unsigned long n2) { + if (n1 == 0) { + return n2; + } + return gcd(n2 % n1, n1); +} + +unsigned long find_module_refresh_time() { + size_t i; + size_t ignore_index; + size_t result; + for (i = 0; i < global_module_count; ++i) { + if (!modules[i].disabled && modules[i].refresh_time != NO_REFRESH) { + result = modules[i].refresh_time; + ignore_index = i; + } + } + for (i = 0; i < global_module_count; ++i) { + if (i == ignore_index) { + continue; + } + if (!modules[i].disabled && modules[i].refresh_time != NO_REFRESH) { + result = gcd(result, modules[i].refresh_time); + } + if (result == 1) { + break; + } + } + return result; +} + static void set_refresh_time() { #ifdef REFRESH_TIME unsigned long refresh_ms = REFRESH_TIME; #else - unsigned long refresh_ms = find_module_refresh_gcf(); + unsigned long refresh_ms = find_module_refresh_time(); if (refresh_ms == 0) { /* if all modules are triggered by signals */ refresh_ms = HOURS(1); /* refresh once an hour */ } @@ -600,22 +534,6 @@ static void setup_signals() { sigprocmask(SIG_BLOCK, &global_real_time_mask, NULL); } -static unsigned long find_module_refresh_gcf() { - size_t refresh_times_length = 0; - unsigned long *refresh_times = NULL; - size_t i; - for (i = 0; i < global_module_count; ++i) { - if (!modules[i].disabled && modules[i].refresh_time != NO_REFRESH) { - refresh_times = qtb_realloc( - refresh_times, sizeof(unsigned long) * ++refresh_times_length); - refresh_times[refresh_times_length - 1] = modules[i].refresh_time; - } - } - unsigned long gcf = find_gcf(refresh_times, refresh_times_length); - qtb_free(refresh_times); - return gcf; -} - static unsigned long timespec_to_miliseconds(struct timespec *ts) { return (ts->tv_sec * 1000) + (ts->tv_nsec / 1000000); }