From 66ee7026da802f02793ce44f6243486ef93a8986 Mon Sep 17 00:00:00 2001 From: simone Date: Mon, 6 May 2024 23:10:12 +0200 Subject: [PATCH] Memory reimplementation --- src/main.c | 112 ++++++++++++++++++++++++++++++++++++++++++---------- src/main.h | 4 +- src/queue.c | 32 +++++++++++++-- src/queue.h | 3 ++ 4 files changed, 127 insertions(+), 24 deletions(-) diff --git a/src/main.c b/src/main.c index eff604d..5ad3e6a 100644 --- a/src/main.c +++ b/src/main.c @@ -19,6 +19,8 @@ static unsigned short ***delim_bins = NULL; static modifiers_t bool_modifiers = {0x0}; static Queue_t *global_queue = NULL; static Queue_t *f_buffer[N_THREAD]; +static size_t memory_max = 0; +static atomic_bool print_exit = false; void gen_bin_to_arr(unsigned short *arr, size_t size, size_t idx, size_t max, size_t cur, size_t min, unsigned short ***out, size_t *out_size) { @@ -45,7 +47,7 @@ static struct option long_options[] = {"last", required_argument, 0, 'l'}, {"only_transformations", no_argument, 0, 'p'}, {"reverse", required_argument, 0, 'r'}, - {"memory", no_argument, 0, 'x'}, + {"memory", required_argument, 0, 'x'}, {"leet", required_argument, 0, 'k'}, {"random", required_argument, 0, 'm'}, {"charset", required_argument, 0, 'i'}, @@ -99,9 +101,8 @@ inline void print_out(char **arr, size_t size, size_t queue_pos) { char finalString[BUFF] = {0x0}; char *all_strings[BUFF] = {0x0}; - size_t run_len = 0, strings_len = 0; + size_t run_len = 0, strings_len = 0, saved_len = 0; size_t lengths[size]; - size_t saved_len = 0; size_t reverse_make_sense = false; for (size_t i = 0; i < size; i++) { @@ -211,6 +212,12 @@ inline void print_out(char **arr, size_t size, size_t queue_pos) { char **copy_buff = (char **)malloc(sizeof(char *) * (strings_len - saved_len)); memcpy(copy_buff, all_strings + saved_len, sizeof(char *) * (strings_len - saved_len)); + if (memory_max > 0) + { + while (f_buffer[queue_pos]->cur >= memory_max) + { + } + } push_queue(f_buffer[queue_pos], copy_buff, (strings_len - saved_len)); for (size_t i = 0; i < saved_len; i++) { @@ -233,14 +240,13 @@ inline void print_out(char **arr, size_t size, size_t queue_pos) inline bool leet_encode(char *str) { bool encoded = false; - while (*str != '\0') + for (char *ptr = str; *ptr != '\0'; ptr++) { - if (leet_map[*str]) + if (leet_map[*ptr]) { - *str = leet_map[*str]; + *ptr = leet_map[*ptr]; encoded = true; } - str++; } return encoded; } @@ -296,6 +302,50 @@ void seq_perm(char **arr, size_t size, size_t queue_pos) } } +void swap_qp(Queue_t *q1, Queue_t *q2) +{ + Queue_t *tmp = q1; + q1 = q2; + q2 = tmp; +} + +void *thread_print(void *in) +{ + Queue_t *iter_queue[N_THREAD]; + memcpy(iter_queue, f_buffer, sizeof(Queue_t *) * N_THREAD); + long iter_size = N_THREAD; + for (;;) + { + for (long i = iter_size - 1; i >= 0; i--) + { + for (size_t j = 0; j < PRINT_THRESH; j++) + { + input_t *pp = pop_list(iter_queue[i]); + if (pp == NULL) + { + if (print_exit == true) + { + swap_qp(iter_queue[i], iter_queue[--iter_size]); + } + break; + } + for (size_t x = 0; x < pp->len; x++) + { + printf("%s\n", pp->aux[x]); + FREE_P(pp->aux[x]); + } + FREE_P(pp->aux); + FREE_P(pp); + } + } + if (!iter_size) + { + return NULL; + } + } + return NULL; +} + void *thread_perm(void *in) { size_t queue_pos = bool_modifiers.memory ? *(size_t *)in : 0; @@ -403,7 +453,7 @@ int main(int argc, char **argv) enum c_t rand_type = _NULL; size_t rand_times = 0, rand_len = 0; setvbuf(stdout, NULL, _IOFBF, PRINT_BUFF); - while ((c = getopt_long(argc, argv, "u:l:pk:c:s:e:r:m:i:x", long_options, &option_index)) != -1) + while ((c = getopt_long(argc, argv, "u:l:pk:c:s:e:r:m:i:x:", long_options, &option_index)) != -1) { switch (c) { @@ -452,6 +502,7 @@ int main(int argc, char **argv) case 'x': { CALL_SET(0, 0, bool_modifiers.memory, true); + ERR("memory max size can't be less than 0", memory_max, strtoul(optarg, NULL, 10)); break; } case 'c': @@ -576,7 +627,7 @@ int main(int argc, char **argv) gen_bin_perms(bin, word_size, 0, max_len, 0, min_len); FREE_P(bin); global_queue->head = global_queue->tail - 1; - pthread_t tworker[N_THREAD]; + pthread_t tworker[N_THREAD], print_w = {0}; memset(&tworker, 0x0, sizeof(tworker)); size_t pos = 0; for (size_t i = 0; i < N_THREAD; i++) @@ -593,28 +644,49 @@ int main(int argc, char **argv) pthread_create(&tworker[i], NULL, thread_perm, NULL); } } + if (memory_max != 0 && bool_modifiers.memory) + { + pthread_create(&print_w, NULL, thread_print, NULL); + } for (size_t i = 0; i < N_THREAD; i++) { pthread_join(tworker[i], NULL); } + print_exit = true; + if (memory_max != 0 && bool_modifiers.memory) + { + pthread_join(print_w, NULL); + } if (bool_modifiers.memory) { - for (size_t k = 0; k < N_THREAD; k++) + if (memory_max == 0) { - Queue_t *current_buffer = f_buffer[k]; - for (size_t i = 0; i < current_buffer->tail; i++) + for (size_t k = 0; k < N_THREAD; k++) { - input_t *current_words = current_buffer->words[i]; - for (size_t j = 0; j < current_words->len; j++) + Queue_t *current_buffer = f_buffer[k]; + for (size_t i = 0; i < current_buffer->tail; i++) { - printf("%s\n", current_words->aux[j]); - free(current_words->aux[j]); + input_t *current_words = current_buffer->words[i]; + for (size_t j = 0; j < current_words->len; j++) + { + printf("%s\n", current_words->aux[j]); + free(current_words->aux[j]); + } + free(current_words->aux); + free(current_words); } - free(current_words->aux); - free(current_words); + FREE_P(current_buffer->words); + FREE_P(current_buffer); + } + } + else + { + for (size_t k = 0; k < N_THREAD; k++) + { + Queue_t *current_buffer = f_buffer[k]; + FREE_P(current_buffer->words); + FREE_P(current_buffer); } - FREE_P(current_buffer->words); - FREE_P(current_buffer); } } FREE_P(global_queue->words); diff --git a/src/main.h b/src/main.h index a8ad22d..057b4e0 100644 --- a/src/main.h +++ b/src/main.h @@ -7,8 +7,9 @@ #include #include #define BUFF 512 -#define N_THREAD 8 +#define N_THREAD 7 #define PRINT_BUFF 64 * 1024 * 1024 +#define PRINT_THRESH 1024 #define FREE_PPP(p, fc, size, sc, size2) \ ({ \ @@ -101,6 +102,7 @@ unsigned **binomial_coefficient(size_t n, size_t k); void free_inputs_optind(void); void exit_usage(char *plus); bool leet_encode(char *str); +void *thread_print(void *in); bool upper_encode(char *str); void reverse(char *str, size_t len); bool palindrome(char *str, size_t len); diff --git a/src/queue.c b/src/queue.c index ab0b27b..db5faf7 100644 --- a/src/queue.c +++ b/src/queue.c @@ -17,8 +17,10 @@ Queue_t *init_queue(size_t size) Q->words = (input_t **)calloc(size, sizeof(input_t *)); UNDEF(Q, "BUCKET_QUEUE_INIT_FAIL"); Q->maxsize = size; - Q->head = 0; Q->tail = 0; + atomic_store(&Q->cur, 0); + atomic_store(&Q->head, 0); + atomic_flag_clear(&Q->taking); return Q; } @@ -31,14 +33,34 @@ void push_queue(Queue_t *Q, char **aux, size_t len) { resize(Q); } + atomic_fetch_add(&Q->cur, 1); Q->words[Q->tail++] = inQueue; } +input_t *pop_list(Queue_t *Q) +{ + input_t *aux = NULL; + while (atomic_flag_test_and_set(&Q->taking)) + { + aux = Q->head >= Q->tail ? NULL : Q->words[Q->head++]; + atomic_flag_clear(&Q->taking); + } + if (aux != NULL) + { + atomic_fetch_sub(&Q->cur, 1); + } + return aux; +} + input_t *pop_queue(Queue_t *Q) { input_t *aux = NULL; long idx = atomic_fetch_sub(&Q->head, 1); aux = idx >= 0 ? Q->words[idx] : NULL; + if (aux != NULL) + { + atomic_fetch_sub(&Q->cur, 1); + } return aux; } @@ -46,6 +68,10 @@ void resize(Queue_t *Q) { size_t old_size = Q->maxsize; Q->maxsize *= 2; - Q->words = (input_t **)realloc(Q->words, sizeof(input_t *) * Q->maxsize); - memset(Q->words + old_size, 0x0, sizeof(input_t *) * (Q->maxsize - old_size)); + while (atomic_flag_test_and_set(&Q->taking)) + { + Q->words = (input_t **)realloc(Q->words, sizeof(input_t *) * Q->maxsize); + memset(Q->words + old_size, 0x0, sizeof(input_t *) * (Q->maxsize - old_size)); + atomic_flag_clear(&Q->taking); + } } diff --git a/src/queue.h b/src/queue.h index c3056f1..ef5422c 100644 --- a/src/queue.h +++ b/src/queue.h @@ -30,6 +30,8 @@ typedef struct Queue { input_t **words; atomic_long head; + atomic_size_t cur; + atomic_flag taking; size_t tail; size_t maxsize; } Queue_t; @@ -38,5 +40,6 @@ Queue_t *init_queue(size_t size); void push_queue(Queue_t *Q, char **aux, size_t len); input_t *pop_queue(Queue_t *Q); void free_queue(Queue_t *Q); +input_t *pop_list(Queue_t *Q); void resize(Queue_t *Q); Queue_t *default_init_queue();