| summaryrefslogtreecommitdiff |
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2017-01-31 16:21:24 +0100 |
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2017-01-31 16:21:24 +0100 |
| commit | 509ac16d892aeb5091f68620247f6815d2e4b5f5 (patch) | |
| tree | c4adebce7791c10c4c362b77f32d4a339e8c8125 /src | |
| parent | 1373211465c34015ee900e097aa87fbffb401187 (diff) | |
Switched to sockets, continuing implementation...
Diffstat (limited to 'src')
30 files changed, 1268 insertions, 315 deletions
diff --git a/src/knowledge/knowledge.c b/src/knowledge/knowledge.c index 463d40b..c9bfc2a 100644 --- a/src/knowledge/knowledge.c +++ b/src/knowledge/knowledge.c @@ -1,5 +1,6 @@ #include <stdlib.h> #include <string.h> +#include <stdio.h> #include <stdint.h> /* defines SIZE_MAX */ #include "../pipe/pipe.h" @@ -9,8 +10,10 @@ /** Basic functions of the ZoO_knowledge structure ****************************/ /* See: "knowledge.h" */ -void ZoO_knowledge_initialize (struct ZoO_knowledge k [const static 1]) +int ZoO_knowledge_initialize (struct ZoO_knowledge k [const restrict static 1]) { + int error; + k->words = (struct ZoO_knowledge_word *) NULL; k->words_length = 0; k->words_sorted = (ZoO_index *) NULL; @@ -18,6 +21,22 @@ void ZoO_knowledge_initialize (struct ZoO_knowledge k [const static 1]) k->sequences = (ZoO_index **) NULL; k->sequences_length = 0; k->sequences_sorted = (ZoO_index *) NULL; + + error = pthread_mutex_init(&(k->mutex), (const pthread_mutexattr_t *) NULL); + + if (error != 0) + { + fprintf + ( + stderr, + "[F] Unable to initialize knowledge mutex: %s.\n", + strerror(error) + ); + + return -1; + } + + return 0; } int ZoO_knowledge_lock_access @@ -26,8 +45,7 @@ int ZoO_knowledge_lock_access const struct ZoO_pipe io [const restrict static 1] ) { - /* TODO */ - return 0; + return pthread_mutex_lock(&(k->mutex)); } void ZoO_knowledge_unlock_access @@ -36,5 +54,5 @@ void ZoO_knowledge_unlock_access const struct ZoO_pipe io [const restrict static 1] ) { - /* TODO */ + pthread_mutex_unlock(&(k->mutex)); } diff --git a/src/knowledge/knowledge.h b/src/knowledge/knowledge.h index c65ee2c..e868943 100644 --- a/src/knowledge/knowledge.h +++ b/src/knowledge/knowledge.h @@ -20,10 +20,7 @@ void ZoO_knowledge_unlock_access const struct ZoO_pipe io [const restrict static 1] ); -void ZoO_knowledge_initialize -( - struct ZoO_knowledge k [const restrict static 1] -); +int ZoO_knowledge_initialize (struct ZoO_knowledge k [const restrict static 1]); void ZoO_knowledge_finalize (struct ZoO_knowledge k [const restrict static 1]); @@ -59,13 +56,12 @@ int ZoO_knowledge_learn_markov_sequence ( struct ZoO_knowledge k [const restrict static 1], const ZoO_index sequence [const restrict static 1], - const ZoO_index sequence_length, - const ZoO_index markov_order, + const ZoO_index markov_order, /* Pre (> markov_order 1) */ ZoO_index sequence_id [const restrict static 1], const struct ZoO_pipe io [const restrict static 1] ); -int ZoO_knowledge_get_following_sequences_ref +int ZoO_knowledge_get_swt_sequences_ref ( const struct ZoO_knowledge k [const static 1], const ZoO_index initial_word, @@ -110,27 +106,67 @@ int ZoO_knowledge_find_word_id ZoO_index result [const restrict static 1] ); -int ZoO_knowledge_find_preceding_words +int ZoO_knowledge_find_tws_targets ( const struct ZoO_knowledge k [const static 1], const ZoO_index sequence [const restrict], const ZoO_index markov_order, - const ZoO_index * restrict preceding_words [const restrict static 1], - const ZoO_index * restrict preceding_words_weights [const restrict static 1], - ZoO_index preceding_words_weights_sum [const restrict static 1], + const ZoO_index * restrict targets [const restrict static 1], + const ZoO_index * restrict targets_weights [const restrict static 1], + ZoO_index targets_weights_sum [const restrict static 1], const struct ZoO_pipe io [const restrict static 1] ); -int ZoO_knowledge_find_following_words +int ZoO_knowledge_find_swt_targets ( const struct ZoO_knowledge k [const static 1], const ZoO_index sequence [const restrict], const size_t sequence_length, const ZoO_index markov_order, - const ZoO_index * restrict following_words [const restrict static 1], - const ZoO_index * restrict following_words_weights [const restrict static 1], - ZoO_index following_words_weights_sum [const restrict static 1], + const ZoO_index * restrict targets [const restrict static 1], + const ZoO_index * restrict targets_weights [const restrict static 1], + ZoO_index targets_weights_sum [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] +); + +int ZoO_knowledge_strengthen_swt +( + struct ZoO_knowledge k [const restrict static 1], + const ZoO_index sequence_id, + const ZoO_index word_id, + const ZoO_index target_id, + const struct ZoO_pipe io [const restrict static 1] +); + +int ZoO_knowledge_strengthen_tws +( + struct ZoO_knowledge k [const restrict static 1], + const ZoO_index target_id, + const ZoO_index word_id, + const ZoO_index sequence_id, const struct ZoO_pipe io [const restrict static 1] ); +/* + * TODO + */ +/* +int ZoO_knowledge_weaken_swt +( + struct ZoO_knowledge k [const restrict static 1], + const ZoO_index sequence_id, + const ZoO_index word_id, + const ZoO_index target_id, + const struct ZoO_pipe io [const restrict static 1] +); + +int ZoO_knowledge_weaken_tws +( + struct ZoO_knowledge k [const restrict static 1], + const ZoO_index target_id, + const ZoO_index word_id, + const ZoO_index sequence_id, + const struct ZoO_pipe io [const restrict static 1] +); +*/ #endif diff --git a/src/knowledge/knowledge_finalize.c b/src/knowledge/knowledge_finalize.c index 9628672..9546650 100644 --- a/src/knowledge/knowledge_finalize.c +++ b/src/knowledge/knowledge_finalize.c @@ -65,8 +65,8 @@ static void knowledge_word_finalize w->word = (ZoO_char *) NULL; } - knowledge_sequence_collection_finalize(&(w->followed)); - knowledge_sequence_collection_finalize(&(w->preceded)); + knowledge_sequence_collection_finalize(&(w->swt)); + knowledge_sequence_collection_finalize(&(w->tws)); } /* See: "knowledge.h" */ @@ -115,4 +115,6 @@ void ZoO_knowledge_finalize (struct ZoO_knowledge k [const restrict static 1]) k->sequences_sorted = (ZoO_index *) NULL; } + + pthread_mutex_destroy(&(k->mutex)); } diff --git a/src/knowledge/knowledge_learn_markov_sequence.c b/src/knowledge/knowledge_learn_markov_sequence.c index 2bd0103..4258c4a 100644 --- a/src/knowledge/knowledge_learn_markov_sequence.c +++ b/src/knowledge/knowledge_learn_markov_sequence.c @@ -143,7 +143,6 @@ static int reallocate_sequences_sorted_list static ZoO_index * copy_sequence ( const ZoO_index base [const restrict static 1], - const ZoO_index base_length, const ZoO_index destination_length, const struct ZoO_pipe io [const restrict static 1] ) @@ -169,45 +168,12 @@ static ZoO_index * copy_sequence return (ZoO_index *) NULL; } - if (base_length == destination_length) - { - memcpy - ( - (void *) result, - (const void *) base, - (((size_t) base_length) * sizeof(ZoO_index)) - ); - } - else if (base[0] == ZoO_START_OF_SEQUENCE_ID) - { - diff = (destination_length - base_length); - - memcpy - ( - (void *) (result + diff), - (const void *) base, - (((size_t) base_length) * sizeof(ZoO_index)) - ); - - for (i = 0; i < diff; ++i) - { - result[i] = ZoO_START_OF_SEQUENCE_ID; - } - } - else if (base[(base_length - 1)] == ZoO_END_OF_SEQUENCE_ID) - { - memcpy - ( - (void *) result, - (const void *) base, - (((size_t) base_length) * sizeof(ZoO_index)) - ); - - for (i = base_length; i < destination_length; ++i) - { - result[i] = ZoO_END_OF_SEQUENCE_ID; - } - } + memcpy + ( + (void *) result, + (const void *) base, + (((size_t) destination_length) * sizeof(ZoO_index)) + ); return result; } @@ -220,7 +186,6 @@ static int add_sequence ( struct ZoO_knowledge k [const restrict static 1], const ZoO_index sequence [const restrict static 1], - const ZoO_index sequence_length, const ZoO_index markov_order, /* Pre (> markov_order 1) */ const ZoO_index sequence_id, const ZoO_index sorted_sequence_id, @@ -241,7 +206,7 @@ static int add_sequence return -1; } - stored_sequence = copy_sequence(sequence, sequence_length, markov_order, io); + stored_sequence = copy_sequence(sequence, (markov_order - 1), io); if (stored_sequence == (ZoO_index *) NULL) { @@ -283,7 +248,6 @@ static int find_sequence ( const struct ZoO_knowledge k [const static 1], const ZoO_index sequence [const restrict static 1], - const ZoO_index sequence_length, const ZoO_index markov_order, /* Pre: (> 1) */ ZoO_index sequence_id [const restrict static 1] ) @@ -317,7 +281,7 @@ static int find_sequence k->sequences[k->sequences_sorted[i]], markov_sequence_length, sequence, - sequence_length + markov_sequence_length ); if (cmp > 0) @@ -359,7 +323,6 @@ int ZoO_knowledge_learn_markov_sequence ( struct ZoO_knowledge k [const restrict static 1], const ZoO_index sequence [const restrict static 1], - const ZoO_index sequence_length, const ZoO_index markov_order, /* Pre (> markov_order 1) */ ZoO_index sequence_id [const restrict static 1], const struct ZoO_pipe io [const restrict static 1] @@ -373,7 +336,6 @@ int ZoO_knowledge_learn_markov_sequence ( k, sequence, - sequence_length, markov_order, sequence_id ) == 0 @@ -390,7 +352,6 @@ int ZoO_knowledge_learn_markov_sequence ( k, sequence, - sequence_length, markov_order, *sequence_id, sorted_id, diff --git a/src/knowledge/knowledge_learn_sequence.c b/src/knowledge/knowledge_learn_sequence.c index 35b6d15..927b186 100644 --- a/src/knowledge/knowledge_learn_sequence.c +++ b/src/knowledge/knowledge_learn_sequence.c @@ -8,38 +8,180 @@ #include "knowledge.h" + + /******************************************************************************/ /** LEARN FOLLOWING SEQUENCE **************************************************/ /******************************************************************************/ -static int add_following_sequence +static void parse_swt_sequence +( + const ZoO_index sequence [const restrict static 1], + const size_t index, + ZoO_index buffer [const restrict static 1], + const ZoO_index buffer_length +) +{ + size_t j; + size_t index_offset; + + index_offset = buffer_length; + + for (j = 0; j < buffer_length; ++j) + { + index_offset = (buffer_length - j); + + if (index >= index_offset) + { + buffer[j] = sequence[index - index_offset]; + } + else + { + buffer[j] = ZoO_START_OF_SEQUENCE_ID; + } + } +} + +static int add_swt_sequence ( struct ZoO_knowledge k [const restrict static 1], const ZoO_index sequence [const restrict static 1], const size_t index, const size_t sequence_length, - const ZoO_index markov_order, + ZoO_index buffer [const restrict static 1], + const ZoO_index buffer_length, const struct ZoO_pipe io [const restrict static 1] ) { - /* TODO */ - return -1; + ZoO_index sequence_id; + + parse_swt_sequence(sequence, index, buffer, buffer_length); + + if + ( + ZoO_knowledge_learn_markov_sequence + ( + k, + buffer, + (buffer_length + 1), + &sequence_id, + io + ) + ) + { + return -1; + } + + if (index == (sequence_length - 1)) + { + return + ZoO_knowledge_strengthen_swt + ( + k, + sequence_id, + sequence[index], + ZoO_END_OF_SEQUENCE_ID, + io + ); + } + else + { + return + ZoO_knowledge_strengthen_swt + ( + k, + sequence_id, + sequence[index], + sequence[index + 1], + io + ); + } } /******************************************************************************/ /** LEARN PRECEDING SEQUENCE **************************************************/ /******************************************************************************/ -static int add_preceding_sequence +static void parse_tws_sequence +( + const ZoO_index sequence [const restrict static 1], + const size_t index, + const size_t sequence_length, + ZoO_index buffer [const restrict static 1], + const ZoO_index buffer_length +) +{ + size_t j; + size_t index_offset; + const size_t remaining_items = (sequence_length - index); + + for (j = 0; j < buffer_length; ++j) + { + index_offset = (j + 1); + + if (remaining_items > index_offset) + { + buffer[j] = sequence[index + index_offset]; + } + else + { + buffer[j] = ZoO_END_OF_SEQUENCE_ID; + } + } +} + +static int add_tws_sequence ( struct ZoO_knowledge k [const restrict static 1], const ZoO_index sequence [const restrict static 1], const size_t index, const size_t sequence_length, - const ZoO_index markov_order, + ZoO_index buffer [const restrict static 1], + const ZoO_index buffer_length, const struct ZoO_pipe io [const restrict static 1] ) { - /* TODO */ - return -1; + ZoO_index sequence_id; + + parse_tws_sequence(sequence, index, sequence_length, buffer, buffer_length); + + if + ( + ZoO_knowledge_learn_markov_sequence + ( + k, + buffer, + (buffer_length + 1), + &sequence_id, + io + ) + ) + { + return -1; + } + + if (index == 0) + { + return + ZoO_knowledge_strengthen_tws + ( + k, + ZoO_START_OF_SEQUENCE_ID, + sequence[index], + sequence_id, + io + ); + } + else + { + return + ZoO_knowledge_strengthen_tws + ( + k, + sequence[index - 1], + sequence[index], + sequence_id, + io + ); + } } /******************************************************************************/ @@ -58,35 +200,49 @@ int ZoO_knowledge_learn_sequence size_t i; const ZoO_index buffer_length = (markov_order - 1); - for (i = 0; i < sequence_length; ++i) + buffer = + (ZoO_index *) calloc + ( + (size_t) buffer_length, + sizeof(ZoO_index) + ); + + if (buffer == (ZoO_index *) NULL) { - k->words[sequence[i]].occurrences += 1; + ZoO_S_ERROR + ( + io, + "Unable to allocate memory required to create markov sequences." + ); + + return -1; + } - add_preceding_sequence + for (i = 0; i < sequence_length; ++i) + { + add_tws_sequence ( k, sequence, i, sequence_length, + buffer, buffer_length, io ); - add_following_sequence + add_swt_sequence ( k, sequence, i, sequence_length, - markov_order, + buffer, + buffer_length, io ); - /* - * TODO: in case of failure, undo part of the word done so far: instead - * of unlearning, just remove the occurrence count of sequences and - * words so that {k} remains coherent. - */ + k->words[sequence[i]].occurrences += 1; } return 0; diff --git a/src/knowledge/knowledge_learn_word.c b/src/knowledge/knowledge_learn_word.c index 33a2bf1..5d932d2 100644 --- a/src/knowledge/knowledge_learn_word.c +++ b/src/knowledge/knowledge_learn_word.c @@ -33,8 +33,8 @@ static void initialize_word w->word_length = 0; w->occurrences = 0; - initialize_sequence_collection(&(w->followed)); - initialize_sequence_collection(&(w->preceded)); + initialize_sequence_collection(&(w->swt)); + initialize_sequence_collection(&(w->tws)); } /******************************************************************************/ diff --git a/src/knowledge/knowledge_search.c b/src/knowledge/knowledge_search.c index 4ea4572..198da1d 100644 --- a/src/knowledge/knowledge_search.c +++ b/src/knowledge/knowledge_search.c @@ -73,14 +73,15 @@ int ZoO_knowledge_find_word_id } } -int ZoO_knowledge_find_preceding_words +/* pre: \length(sequence) >= markov_order */ +int ZoO_knowledge_find_tws_targets ( const struct ZoO_knowledge k [const static 1], - const ZoO_index sequence [const restrict], + const ZoO_index sequence [restrict static 1], const ZoO_index markov_order, /* Pre: (> 0) */ - const ZoO_index * restrict preceding_words [const restrict static 1], - const ZoO_index * restrict preceding_words_weights [const restrict static 1], - ZoO_index preceding_words_weights_sum [const restrict static 1], + const ZoO_index * restrict targets [const restrict static 1], + const ZoO_index * restrict targets_weights [const restrict static 1], + ZoO_index targets_weights_sum [const restrict static 1], const struct ZoO_pipe io [const restrict static 1] ) { @@ -89,19 +90,23 @@ int ZoO_knowledge_find_preceding_words ZoO_index i, current_min, current_max, local_sequence; const ZoO_index * restrict candidate; const ZoO_index markov_sequence_length = (markov_order - 1); - const ZoO_index word = sequence[markov_sequence_length]; + const ZoO_index word = sequence[0]; - if (word >= k->words_length) + if + ( + (word >= k->words_length) + || (k->words[word].occurrences == 0) + ) { ZoO_S_ERROR ( io, - "Attempting to find the preceding words of an unknown word." + "Attempting to find the TWS targets of an unknown word." ); - *preceding_words = (const ZoO_index *) NULL; - *preceding_words_weights = (const ZoO_index *) NULL; - *preceding_words_weights_sum = 0; + *targets = (const ZoO_index *) NULL; + *targets_weights = (const ZoO_index *) NULL; + *targets_weights_sum = 0; return -1; } @@ -110,30 +115,34 @@ int ZoO_knowledge_find_preceding_words if (markov_order == 1) { /* Special case: empty sequences. */ - *preceding_words = (const ZoO_index *) k->words[word].preceded.targets; + *targets = (const ZoO_index *) k->words[word].tws.targets; - *preceding_words_weights = - (const ZoO_index *) k->words[word].preceded.targets_occurrences; + *targets_weights = + (const ZoO_index *) k->words[word].tws.targets_occurrences; - *preceding_words_weights_sum = k->words[word].occurrences; + *targets_weights_sum = k->words[word].occurrences; return 0; } + + /* pre: \length(sequence) >= markov_order */ + /* markov_order > 1 */ + sequence += 1; /* get the relevant part of the sequence. */ + /* Handles the case where the list is empty ********************************/ - current_max = k->words[word].preceded.sequences_ref_length; + current_max = k->words[word].tws.sequences_ref_length; if (current_max == 0) { - *preceding_words = (const ZoO_index *) NULL; - *preceding_words_weights = (const ZoO_index *) NULL; - *preceding_words_weights_sum = 0; + *targets = (const ZoO_index *) NULL; + *targets_weights = (const ZoO_index *) NULL; + *targets_weights_sum = 0; ZoO_S_ERROR ( io, - "Attempting to find the preceding words of a sequence that never had " - "any." + "Attempting to find the TWS targets of a sequence that never had any." ); return -2; @@ -147,12 +156,12 @@ int ZoO_knowledge_find_preceding_words { i = (current_min + ((current_max - current_min) / 2)); - local_sequence = k->words[word].preceded.sequences_ref_sorted[i]; + local_sequence = k->words[word].tws.sequences_ref_sorted[i]; (void) ZoO_knowledge_get_sequence ( k, - k->words[word].preceded.sequences_ref[local_sequence], + k->words[word].tws.sequences_ref[local_sequence], &candidate, io ); @@ -172,9 +181,9 @@ int ZoO_knowledge_find_preceding_words if (current_min > current_max) { - *preceding_words = (const ZoO_index *) NULL; - *preceding_words_weights = (const ZoO_index *) NULL; - *preceding_words_weights_sum = 0; + *targets = (const ZoO_index *) NULL; + *targets_weights = (const ZoO_index *) NULL; + *targets_weights_sum = 0; return -2; } @@ -183,9 +192,9 @@ int ZoO_knowledge_find_preceding_words { if ((current_min > current_max) || (i == 0)) { - *preceding_words = (const ZoO_index *) NULL; - *preceding_words_weights = (const ZoO_index *) NULL; - *preceding_words_weights_sum = 0; + *targets = (const ZoO_index *) NULL; + *targets_weights = (const ZoO_index *) NULL; + *targets_weights_sum = 0; return -2; } @@ -194,28 +203,28 @@ int ZoO_knowledge_find_preceding_words } else { - *preceding_words = k->words[word].preceded.targets[local_sequence]; + *targets = k->words[word].tws.targets[local_sequence]; - *preceding_words_weights = - k->words[word].preceded.targets_occurrences[local_sequence]; + *targets_weights = + k->words[word].tws.targets_occurrences[local_sequence]; - *preceding_words_weights_sum = - k->words[word].preceded.occurrences[local_sequence]; + *targets_weights_sum = + k->words[word].tws.occurrences[local_sequence]; return 0; } } } -int ZoO_knowledge_find_following_words +int ZoO_knowledge_find_swt_targets ( const struct ZoO_knowledge k [const static 1], - const ZoO_index sequence [const restrict], + const ZoO_index sequence [restrict static 1], const size_t sequence_length, const ZoO_index markov_order, - const ZoO_index * restrict following_words [const restrict static 1], - const ZoO_index * restrict following_words_weights [const restrict static 1], - ZoO_index following_words_weights_sum [const restrict static 1], + const ZoO_index * restrict targets [const restrict static 1], + const ZoO_index * restrict targets_weights [const restrict static 1], + ZoO_index targets_weights_sum [const restrict static 1], const struct ZoO_pipe io [const restrict static 1] ) { @@ -224,21 +233,23 @@ int ZoO_knowledge_find_following_words ZoO_index i, current_min, current_max, local_sequence; const ZoO_index * restrict candidate; const ZoO_index markov_sequence_length = (markov_order - 1); - const size_t sequence_offset = - ((sequence_length - ((size_t) markov_sequence_length)) - 1); - const ZoO_index word = sequence[sequence_offset]; + const ZoO_index word = sequence[sequence_length - 1]; - if (word >= k->words_length) + if + ( + (word >= k->words_length) + || (k->words[word].occurrences == 0) + ) { ZoO_S_ERROR ( io, - "Attempting to find the following words of an unknown word." + "Attempting to find the SWT targets of an unknown word." ); - *following_words = (const ZoO_index *) NULL; - *following_words_weights = (const ZoO_index *) NULL; - *following_words_weights_sum = 0; + *targets = (const ZoO_index *) NULL; + *targets_weights = (const ZoO_index *) NULL; + *targets_weights_sum = 0; return -1; } @@ -246,30 +257,30 @@ int ZoO_knowledge_find_following_words if (markov_order == 1) { /* Special case: empty sequences. */ - *following_words = (const ZoO_index *) k->words[word].preceded.targets; + *targets = (const ZoO_index *) k->words[word].swt.targets; - *following_words_weights = - (const ZoO_index *) k->words[word].preceded.targets_occurrences; + *targets_weights = + (const ZoO_index *) k->words[word].swt.targets_occurrences; - *following_words_weights_sum = k->words[word].occurrences; + *targets_weights_sum = k->words[word].occurrences; return 0; } + sequence = (sequence + (sequence_length - markov_order)); /* Handles the case where the list is empty ********************************/ - current_max = k->words[word].preceded.sequences_ref_length; + current_max = k->words[word].swt.sequences_ref_length; if (current_max == 0) { - *following_words = (const ZoO_index *) NULL; - *following_words_weights = (const ZoO_index *) NULL; - *following_words_weights_sum = 0; + *targets = (const ZoO_index *) NULL; + *targets_weights = (const ZoO_index *) NULL; + *targets_weights_sum = 0; ZoO_S_WARNING ( io, - "Attempting to find the following words of a sequence that never had " - "any." + "Attempting to find the SWT targets of a sequence that never had any." ); return -2; @@ -283,12 +294,12 @@ int ZoO_knowledge_find_following_words { i = (current_min + ((current_max - current_min) / 2)); - local_sequence = k->words[word].followed.sequences_ref_sorted[i]; + local_sequence = k->words[word].swt.sequences_ref_sorted[i]; (void) ZoO_knowledge_get_sequence ( k, - k->words[word].followed.sequences_ref[local_sequence], + k->words[word].swt.sequences_ref[local_sequence], &candidate, io ); @@ -296,7 +307,7 @@ int ZoO_knowledge_find_following_words cmp = ZoO_sequence_cmp ( - (sequence + sequence_offset), + sequence, markov_sequence_length, candidate, markov_sequence_length @@ -308,9 +319,9 @@ int ZoO_knowledge_find_following_words if (current_min > current_max) { - *following_words = (const ZoO_index *) NULL; - *following_words_weights = (const ZoO_index *) NULL; - *following_words_weights_sum = 0; + *targets = (const ZoO_index *) NULL; + *targets_weights = (const ZoO_index *) NULL; + *targets_weights_sum = 0; return -2; } @@ -319,9 +330,9 @@ int ZoO_knowledge_find_following_words { if ((current_min > current_max) || (i == 0)) { - *following_words = (const ZoO_index *) NULL; - *following_words_weights = (const ZoO_index *) NULL; - *following_words_weights_sum = 0; + *targets = (const ZoO_index *) NULL; + *targets_weights = (const ZoO_index *) NULL; + *targets_weights_sum = 0; return -2; } @@ -330,13 +341,13 @@ int ZoO_knowledge_find_following_words } else { - *following_words = k->words[word].followed.targets[local_sequence]; + *targets = k->words[word].swt.targets[local_sequence]; - *following_words_weights = - k->words[word].followed.targets_occurrences[local_sequence]; + *targets_weights = + k->words[word].swt.targets_occurrences[local_sequence]; - *following_words_weights_sum = - k->words[word].followed.occurrences[local_sequence]; + *targets_weights_sum = + k->words[word].swt.occurrences[local_sequence]; return 0; } diff --git a/src/knowledge/knowledge_swt_tws_modifications.c b/src/knowledge/knowledge_swt_tws_modifications.c new file mode 100644 index 0000000..87305f2 --- /dev/null +++ b/src/knowledge/knowledge_swt_tws_modifications.c @@ -0,0 +1,29 @@ +#include "knowledge.h" + +int ZoO_knowledge_strengthen_swt +( + struct ZoO_knowledge k [const restrict static 1], + const ZoO_index sequence_id, + const ZoO_index word_id, + const ZoO_index target_id, + const struct ZoO_pipe io [const restrict static 1] +) +{ + /* TODO */ + + return -1; +} + +int ZoO_knowledge_strengthen_tws +( + struct ZoO_knowledge k [const restrict static 1], + const ZoO_index target_id, + const ZoO_index word_id, + const ZoO_index sequence_id, + const struct ZoO_pipe io [const restrict static 1] +) +{ + /* TODO */ + + return -1; +} diff --git a/src/knowledge/knowledge_types.h b/src/knowledge/knowledge_types.h index 4962991..9db77bd 100644 --- a/src/knowledge/knowledge_types.h +++ b/src/knowledge/knowledge_types.h @@ -1,6 +1,8 @@ #ifndef _ZoO_KNOWLEDGE_KNOWLEDGE_TYPES_H_ #define _ZoO_KNOWLEDGE_KNOWLEDGE_TYPES_H_ +#include <pthread.h> + #include "../core/index_types.h" #include "../core/char_types.h" @@ -20,8 +22,12 @@ struct ZoO_knowledge_word const ZoO_char * word; ZoO_index word_length; ZoO_index occurrences; - struct ZoO_knowledge_sequence_collection followed; - struct ZoO_knowledge_sequence_collection preceded; + + /* [Sequence] [Word] [Target] */ + struct ZoO_knowledge_sequence_collection swt; + + /* [Target] [Word] [Sequence] */ + struct ZoO_knowledge_sequence_collection tws; }; struct ZoO_knowledge @@ -32,6 +38,7 @@ struct ZoO_knowledge ZoO_index ** sequences; ZoO_index sequences_length; ZoO_index * sequences_sorted; + pthread_mutex_t mutex; }; #endif diff --git a/src/pipe/pipe.c b/src/pipe/pipe.c deleted file mode 100644 index 8f414f5..0000000 --- a/src/pipe/pipe.c +++ /dev/null @@ -1 +0,0 @@ -/* TODO */ diff --git a/src/pipe/pipe.h b/src/pipe/pipe.h index 3c5fd44..9b9445c 100644 --- a/src/pipe/pipe.h +++ b/src/pipe/pipe.h @@ -142,6 +142,4 @@ ZoO_PRINT_S_STDERR(pipe, "F", str);\ }\ ) - -/* TODO: add missing pipe functions */ #endif diff --git a/src/pipe/pipe_types.h b/src/pipe/pipe_types.h index cfeb514..91cf0c3 100644 --- a/src/pipe/pipe_types.h +++ b/src/pipe/pipe_types.h @@ -1,6 +1,8 @@ #ifndef _ZoO_PIPE_PIPE_TYPES_H_ #define _ZoO_PIPE_PIPE_TYPES_H_ +#define ZoO_PIPE_NAME_LENGTH 255 + #include <stdio.h> struct ZoO_pipe @@ -11,8 +13,8 @@ struct ZoO_pipe struct ZoO_pipe_names { - char request_pipe[255]; - char reply_pipe[255]; + char request_pipe[ZoO_PIPE_NAME_LENGTH]; + char reply_pipe[ZoO_PIPE_NAME_LENGTH]; }; // const struct ZoO_pipe io [const restrict static 1] diff --git a/src/sequence/sequence_creation.c b/src/sequence/sequence_creation.c index e8ae2a1..429b58c 100644 --- a/src/sequence/sequence_creation.c +++ b/src/sequence/sequence_creation.c @@ -86,7 +86,7 @@ static int extend_left if ( - ZoO_knowledge_find_preceding_words + ZoO_knowledge_find_tws_targets ( k, *sequence, @@ -272,7 +272,7 @@ static int extend_right if ( - ZoO_knowledge_find_following_words + ZoO_knowledge_find_swt_targets ( k, *sequence, @@ -447,12 +447,12 @@ static int initialize_sequence const struct ZoO_pipe io [const restrict static 1] ) { - const ZoO_index * restrict following_sequences_ref; + const ZoO_index * restrict swt_sequences_ref; const ZoO_index * restrict chosen_sequence; - const ZoO_index * restrict following_sequences_weights; - ZoO_index following_sequences_weights_sum; + const ZoO_index * restrict swt_sequences_weights; + ZoO_index swt_sequences_weights_sum; - sequence[0] = initial_word; + sequence[(markov_order - 1)] = initial_word; if (markov_order == 1) { @@ -463,13 +463,13 @@ static int initialize_sequence if ( - ZoO_knowledge_get_following_sequences_ref + ZoO_knowledge_get_swt_sequences_ref ( k, initial_word, - &following_sequences_ref, - &following_sequences_weights, - &following_sequences_weights_sum, + &swt_sequences_ref, + &swt_sequences_weights, + &swt_sequences_weights_sum, io ) < 0 ) @@ -489,12 +489,12 @@ static int initialize_sequence (void) ZoO_knowledge_get_sequence ( k, - following_sequences_ref + swt_sequences_ref [ weighted_random_pick ( - following_sequences_weights, - following_sequences_weights_sum + swt_sequences_weights, + swt_sequences_weights_sum ) ], &chosen_sequence, @@ -504,7 +504,7 @@ static int initialize_sequence /* Safe if 'allocate_initial_sequence' succeeded. */ memcpy ( - (void *) (sequence + 1), + (void *) sequence, (const void *) chosen_sequence, ((((size_t) markov_order) - 1) * sizeof(ZoO_index)) ); diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt index 2d1beaa..b3f0c15 100644 --- a/src/server/CMakeLists.txt +++ b/src/server/CMakeLists.txt @@ -1,7 +1,16 @@ set( SRC_FILES ${SRC_FILES} ${CMAKE_CURRENT_SOURCE_DIR}/server.c + ${CMAKE_CURRENT_SOURCE_DIR}/server_create_socket.c + ${CMAKE_CURRENT_SOURCE_DIR}/server_finalize.c + ${CMAKE_CURRENT_SOURCE_DIR}/server_initialize.c + ${CMAKE_CURRENT_SOURCE_DIR}/server_joining_threads.c + ${CMAKE_CURRENT_SOURCE_DIR}/server_new_connection.c + ${CMAKE_CURRENT_SOURCE_DIR}/server_signals.c + ${CMAKE_CURRENT_SOURCE_DIR}/server_wait_for_event.c ${CMAKE_CURRENT_SOURCE_DIR}/server_worker.c + ${CMAKE_CURRENT_SOURCE_DIR}/server_worker_handle_request.c + ${CMAKE_CURRENT_SOURCE_DIR}/server_worker_receive.c ) set(SRC_FILES ${SRC_FILES} PARENT_SCOPE) diff --git a/src/server/server.c b/src/server/server.c index 8a75615..874f5eb 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -1,72 +1,81 @@ #include <signal.h> +#include <string.h> #include <stdio.h> #include "../parameters/parameters.h" #include "server.h" -volatile char ZoO_SERVER_IS_RUNNING = (char) 1; - -static void request_termination (int const signo) +int ZoO_server_main +( + const struct ZoO_parameters params [const restrict static 1] +) { - if ((signo == SIGINT) || (signo == SIGTERM)) + struct ZoO_server server; + ZoO_index retries; + + if (ZoO_server_set_signal_handlers < 0) { - ZoO_SERVER_IS_RUNNING = (char) 0; + return -1; } -} -int ZoO_server_main (const struct ZoO_parameters params) -{ - struct ZoO_server server; - struct ZoO_server_message msg_buffer; - struct ZoO_server_worker_parameters worker_params; - - if - ( - ZoO_server_initialize - ( - &server, - ZoO_parameters_get_session_name(¶ms) - ) < 0 - ) + if (ZoO_server_initialize(&server, params) < 0) { return -1; } - ZoO_server_worker_initialize_parameters - ( - &worker_params, - &server, - &msg_buffer, - ¶ms - ); - - while ((ZoO_SERVER_IS_RUNNING == (char) 1) || (server.running_threads > 0)) + while (ZoO_server_is_running()) { - if (ZoO_server_receive_message(&server, &msg_buffer) < 0) + switch (ZoO_server_wait_for_new_event(&server)) { - ZoO_server_no_mq_termination(&server); + case 0: /* Timed out or signal'd. */ + ZoO_server_handle_joining_threads(&server); + + retries = 0; + + break; + + case 1: /* New client attempted connection. */ + ZoO_server_handle_joining_threads(&server); + (void) ZoO_server_handle_new_connection(&server); - break; + retries = 0; + + break; + + case -1: /* Something bad happened. */ + retries += 1; + + if (retries == ZoO_SERVER_MAX_RETRIES) + { + ZoO_server_finalize(&server); + + return -1; + } + + break; } + } - switch (msg_buffer.type) + /* Waiting for the threads to join... */ + while (server.workers.currently_running > 0) + { + switch (ZoO_server_wait_for_new_event(&server)) { - case 'C': /* Client request */ - ZoO_server_add_worker(&server, &worker_params); + case 0: /* Timed out. */ + case 1: /* New client attempted connection. */ + ZoO_server_handle_joining_threads(&server); break; - case 'J': /* Join request */ - ZoO_server_finalize_worker(&server, &msg_buffer); - break; + case -1: /* Something bad happened. */ + retries += 1; + + if (retries == ZoO_SERVER_MAX_RETRIES) + { + ZoO_server_finalize(&server); - default: - fprintf - ( - stderr, - "[W] Received message with unknown type '%c'.\n", - msg_buffer.type - ); + return -1; + } break; } } diff --git a/src/server/server.h b/src/server/server.h index f6aa0de..36ec4ce 100644 --- a/src/server/server.h +++ b/src/server/server.h @@ -5,36 +5,54 @@ #include "server_types.h" -int ZoO_server_cleanup_session (const char * session); - int ZoO_server_initialize ( - struct ZoO_server [const restrict static 1], - const char * session + struct ZoO_server server [const restrict static 1], + const struct ZoO_parameters params [const restrict static 1] +); + +int ZoO_server_socket_open +( + struct ZoO_server_socket server_socket [const restrict static 1], + const char socket_name [const restrict static 1] +); + +void ZoO_server_request_termination (void); +int ZoO_server_is_running (void); +int ZoO_server_set_signal_handlers (void); + +int ZoO_server_main +( + const struct ZoO_parameters params [const restrict static 1] ); -int ZoO_server_main (const struct ZoO_parameters params); -int ZoO_server_finalize (struct ZoO_server [const restrict static 1]); +void ZoO_server_finalize (struct ZoO_server [const restrict static 1]); -void ZoO_server_no_mq_termination (struct ZoO_server [const restrict static 1]); +int ZoO_server_wait_for_new_event +( + struct ZoO_server server [const restrict static 1] +); -int ZoO_server_receive_message +void ZoO_server_handle_joining_threads ( - struct ZoO_server [const restrict static 1], - struct ZoO_server_message msg_buffer [const restrict static 1] + struct ZoO_server server [const restrict static 1] ); -int ZoO_server_add_worker +int ZoO_server_handle_new_connection +( + struct ZoO_server server [const restrict static 1] +); + +void * ZoO_server_worker_main (void * input); + +int ZoO_server_worker_receive ( - struct ZoO_server s [const restrict static 1], - struct ZoO_server_message msg_buffer [const restrict static 1], - struct ZoO_worker_parameters worker_params [const restrict static 1] + struct ZoO_server_worker worker [const restrict static 1] ); -int ZoO_server_finalize_worker +int ZoO_server_worker_handle_request ( - struct ZoO_server [const restrict static 1], - struct ZoO_server_message msg_buffer [const restrict static 1] + struct ZoO_server_worker worker [const restrict static 1] ); #endif diff --git a/src/server/server_add_server_worker.c b/src/server/server_add_server_worker.c deleted file mode 100644 index cae10fd..0000000 --- a/src/server/server_add_server_worker.c +++ /dev/null @@ -1,13 +0,0 @@ -#include <pthread.h> - -#include "server.h" - -int ZoO_server_add_worker -( - struct ZoO_server s [const restrict static 1], - struct ZoO_server_message msg_buffer [const restrict static 1] -) -{ - /* TODO */ - return -1; -} diff --git a/src/server/server_create_socket.c b/src/server/server_create_socket.c new file mode 100644 index 0000000..77e55b7 --- /dev/null +++ b/src/server/server_create_socket.c @@ -0,0 +1,188 @@ +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#include <sys/socket.h> +#include <sys/un.h> + +#include "server.h" + +static int create_socket (int result [const restrict static 1]) +{ + const int old_errno = errno; + + errno = 0; + *result = socket(AF_UNIX, SOCK_STREAM, 0); + + if (*result == -1) + { + fprintf + ( + stderr, + "[F] Unable to create server socket: %s.\n", + strerror(errno) + ); + + errno = old_errno; + + return -1; + } + + errno = old_errno; + + return 0; +} + +static int bind_socket +( + const int socket, + const char socket_name [const restrict static 1] +) +{ + struct sockaddr_un addr; + const int old_errno = errno; + + errno = 0; + memset(&addr, 0, sizeof(struct sockaddr_un)); + + addr.sun_family = AF_UNIX; + + /* addr.sun_path == 108. Using 107 ensure null-termination. */ + strncpy(addr.sun_path, socket_name, 107); + + errno = old_errno; + + if + ( + bind + ( + socket, + (const struct sockaddr *) &addr, + (socklen_t) sizeof(struct sockaddr_un) + ) != 0 + ) + { + fprintf + ( + stderr, + "[F] Unable to bind server socket to %s: %s.\n", + socket_name, + strerror(errno) + ); + + errno = old_errno; + + return -1; + } + + errno = old_errno; + + return 0; +} + +static int set_socket_to_unblocking (const int socket) +{ + int current_flags; + const int old_errno = errno; + + current_flags = fcntl(socket, F_GETFD); + + if (current_flags == -1) + { + fprintf + ( + stderr, + "[F] Unable to get server socket properties: %s.\n", + strerror(errno) + ); + + errno = old_errno; + + return -1; + } + + /* current_flags = current_flags & (~O_NONBLOCK); */ + + current_flags = fcntl(socket, F_SETFD, (current_flags | O_NONBLOCK)); + + if (current_flags == -1) + { + fprintf + ( + stderr, + "[F] Unable to set server socket properties: %s.\n", + strerror(errno) + ); + + errno = old_errno; + + return -2; + } + + errno = old_errno; + + return 0; +} + +static int set_socket_as_listener (const int socket) +{ + const int old_errno = errno; + + if (listen(socket, ZoO_SERVER_SOCKET_LISTEN_BACKLOG) != 0) + { + fprintf + ( + stderr, + "[F] Unable to set server socket properties: %s.\n", + strerror(errno) + ); + + errno = old_errno; + + return -1; + } + + errno = old_errno; + + return 0; +} + +int ZoO_server_socket_open +( + struct ZoO_server_socket server_socket [const restrict static 1], + const char socket_name [const restrict static 1] +) +{ + if (create_socket(&(server_socket->file_descriptor)) < 0) + { + return -1; + } + + if (bind_socket(server_socket->file_descriptor, socket_name) < 0) + { + close(server_socket->file_descriptor); + + return -1; + } + + if (set_socket_to_unblocking(server_socket->file_descriptor) < 0) + { + close(server_socket->file_descriptor); + + return -1; + } + + if (set_socket_as_listener(server_socket->file_descriptor) < 0) + { + close(server_socket->file_descriptor); + + return -1; + } + + FD_ZERO(&(server_socket->as_a_set)); + FD_SET(server_socket->file_descriptor, &(server_socket->as_a_set)); + + return 0; +} diff --git a/src/server/server_finalize.c b/src/server/server_finalize.c new file mode 100644 index 0000000..c38fb7d --- /dev/null +++ b/src/server/server_finalize.c @@ -0,0 +1,42 @@ +#include <stdlib.h> +#include <unistd.h> + +#include "../parameters/parameters.h" + +#include "server.h" + +static void finalize_thread_collection +( + struct ZoO_server_thread_collection workers [const restrict static 1] +) +{ + free((void *) workers->threads); + + workers->threads_capacity = 0; + + pthread_mutex_destroy(&(workers->mutex)); + pthread_barrier_destroy(&(workers->barrier)); + + workers->currently_running = 0; +} + +static void finalize_socket +( + struct ZoO_server_socket socket [const restrict static 1] +) +{ + FD_ZERO(&(socket->as_a_set)); + + close(socket->file_descriptor); + + socket->file_descriptor = -1; +} + +void ZoO_server_finalize +( + struct ZoO_server server [const restrict static 1] +) +{ + finalize_thread_collection(&(server->workers)); + finalize_socket(&(server->socket)); +} diff --git a/src/server/server_initialize.c b/src/server/server_initialize.c new file mode 100644 index 0000000..9213156 --- /dev/null +++ b/src/server/server_initialize.c @@ -0,0 +1,99 @@ +#include <signal.h> +#include <string.h> +#include <stdio.h> + +#include "../parameters/parameters.h" + +#include "server.h" + +static int initialize_worker_collection +( + struct ZoO_server_thread_collection c [const restrict static 1] +) +{ + int error; + + c->threads = (struct ZoO_server_thread_data *) NULL; + c->threads_capacity = 0; + c->currently_running = 0; + + error = + pthread_mutex_init + ( + &(c->mutex), + (const pthread_mutexattr_t *) NULL + ); + + if (error != 0) + { + fprintf + ( + stderr, + "[F] Unable to initialize worker collection's mutex: %s.\n", + strerror(error) + ); + + return -1; + } + + error = + pthread_barrier_init + ( + &(c->barrier), + (const pthread_barrierattr_t *) NULL, + 2 + ); + + if (error != 0) + { + fprintf + ( + stderr, + "[F] Unable to initialize worker collection's barrier: %s.\n", + strerror(error) + ); + + return -1; + } + + return 0; +} + +void initialize_thread_parameters +( + struct ZoO_server server [const restrict static 1], + const struct ZoO_parameters params [const restrict static 1] +) +{ + server->thread_params.thread_collection = &(server->workers); + server->thread_params.server_params = params; + server->thread_params.socket = -1; +} + +int ZoO_server_initialize +( + struct ZoO_server server [const restrict static 1], + const struct ZoO_parameters params [const restrict static 1] +) +{ + if (initialize_worker_collection(&(server->workers)) < 0) + { + return -1; + } + + if + ( + ZoO_server_socket_open + ( + &(server->socket), + ZoO_parameters_get_session_name(params) + ) < 0 + ) + { + return -2; + } + + initialize_thread_parameters(server, params); + + return 0; +} diff --git a/src/server/server_joining_threads.c b/src/server/server_joining_threads.c new file mode 100644 index 0000000..48b5ac6 --- /dev/null +++ b/src/server/server_joining_threads.c @@ -0,0 +1,36 @@ +#include <sys/socket.h> + +#include <errno.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <unistd.h> + +#include "../parameters/parameters.h" + +#include "server.h" + +void ZoO_server_handle_joining_threads +( + struct ZoO_server server [const restrict static 1] +) +{ + ZoO_index i; + + pthread_mutex_lock(&(server->workers.mutex)); + + for (i = 0; i < server->workers.threads_capacity; ++i) + { + if (server->workers.threads[i].state == ZoO_SERVER_JOINING_THREAD) + { + pthread_join(server->workers.threads[i].posix_id, (void **) NULL); + + server->workers.threads[i].state = ZoO_SERVER_NO_THREAD; + + server->workers.currently_running -= 1; + } + } + + pthread_mutex_unlock(&(server->workers.mutex)); +} diff --git a/src/server/server_new_connection.c b/src/server/server_new_connection.c new file mode 100644 index 0000000..5392de5 --- /dev/null +++ b/src/server/server_new_connection.c @@ -0,0 +1,181 @@ +#include <sys/socket.h> + +#include <errno.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <unistd.h> + +#include "../parameters/parameters.h" + +#include "server.h" + +static int get_new_socket (struct ZoO_server server [const restrict static 1]) +{ + const int old_errno = errno; + + server->thread_params.socket = + accept + ( + server->socket.file_descriptor, + (struct sockaddr *) NULL, + (socklen_t *) NULL + ); + + if (server->thread_params.socket == -1) + { + fprintf + ( + stderr, + "[E] Unable to accept on the server's socket: %s.\n", + strerror(errno) + ); + + errno = old_errno; + + return -1; + } + + errno = old_errno; + + return 0; +} + +static int get_new_thread (struct ZoO_server server [const restrict static 1]) +{ + struct ZoO_server_thread_data * new_threads; + ZoO_index i; + + pthread_mutex_lock(&(server->workers.mutex)); + + for (i = 0; i < server->workers.threads_capacity; ++i) + { + if (server->workers.threads[i].state == ZoO_SERVER_NO_THREAD) + { + server->thread_params.thread_id = i; + + pthread_mutex_unlock(&(server->workers.mutex)); + + return 0; + } + } + + if + ( + (server->workers.threads_capacity == ZoO_INDEX_MAX) + || + ( + (size_t) (server->workers.threads_capacity + 1) + > (SIZE_MAX / sizeof(struct ZoO_server_thread_data)) + ) + ) + { + fprintf + ( + stderr, + "[E] Maximum number of concurrent threads attained, unable to add" + " more.\n" + ); + + pthread_mutex_unlock(&(server->workers.mutex)); + + return -1; + } + + server->thread_params.thread_id = server->workers.threads_capacity; + server->workers.threads_capacity += 1; + + new_threads = + (struct ZoO_server_thread_data *) realloc + ( + &(server->workers.threads), + ( + sizeof(struct ZoO_server_thread_data) + * ((size_t) server->workers.threads_capacity) + ) + ); + + if (new_threads == ((struct ZoO_server_thread_data *) NULL)) + { + fprintf + ( + stderr, + "[E] Reallocation of the threads' data list failed.\n" + ); + + pthread_mutex_unlock(&(server->workers.mutex)); + + return -1; + } + + server->workers.threads = new_threads; + + pthread_mutex_unlock(&(server->workers.mutex)); + + return 0; +} + +static int spawn_thread (struct ZoO_server server [const restrict static 1]) +{ + const ZoO_index thread_id = server->thread_params.thread_id; + int error; + + server->workers.threads[thread_id].state = ZoO_SERVER_RUNNING_THREAD; + + error = + pthread_create + ( + &(server->workers.threads[thread_id].posix_id), + (const pthread_attr_t *) NULL, + ZoO_server_worker_main, + (void *) &(server->thread_params) + ); + + if (error != 0) + { + fprintf + ( + stderr, + "[E] Unable to spawn thread: %s.\n", + strerror(error) + ); + + server->workers.threads[thread_id].state = ZoO_SERVER_NO_THREAD; + + return -1; + } + + pthread_barrier_wait(&(server->workers.barrier)); + + server->workers.currently_running += 1; + + return 0; +} + +int ZoO_server_handle_new_connection +( + struct ZoO_server server [const restrict static 1] +) +{ + if (get_new_socket(server) < 0) + { + return -1; + } + + if (get_new_thread(server) < 0) + { + close(server->thread_params.socket); + + return -2; + } + + if (spawn_thread(server) < 0) + { + close(server->thread_params.socket); + + return -3; + } + + return 0; +} diff --git a/src/server/server_signal.c b/src/server/server_signal.c new file mode 100644 index 0000000..97137e8 --- /dev/null +++ b/src/server/server_signal.c @@ -0,0 +1,41 @@ +#include <signal.h> +#include <string.h> +#include <stdio.h> + +#include "server.h" + +static volatile char ZoO_SERVER_IS_RUNNING = (char) 1; + +static void request_termination (int const signo) +{ + if ((signo == SIGINT) || (signo == SIGTERM)) + { + ZoO_server_request_termination(); + } +} + +void ZoO_server_request_termination (void) +{ + ZoO_SERVER_IS_RUNNING = (char) 0; +} + +int ZoO_server_is_running (void) +{ + return (int) ZoO_SERVER_IS_RUNNING; +} + +int ZoO_server_set_signal_handlers (void) +{ + struct sigaction act; + + /* + act.sa_handler = request_termination; + act.sa_mask = + act.sa_flags = + act.sa_restorer = + */ + + /* TODO */ + + return -1; +} diff --git a/src/server/server_types.h b/src/server/server_types.h index aeb0ec8..99959f5 100644 --- a/src/server/server_types.h +++ b/src/server/server_types.h @@ -1,27 +1,70 @@ #ifndef _ZoO_SERVER_SERVER_TYPES_H_ #define _ZoO_SERVER_SERVER_TYPES_H_ -#include <mqueue.h> +#include <sys/time.h> + +#include <pthread.h> #include "../core/index.h" #include "../pipe/pipe_types.h" -struct ZoO_server_message +#define ZoO_SERVER_MAX_RETRIES 10 +#define ZoO_SERVER_BUFFER_SIZE 0 + +#define ZoO_SERVER_SOCKET_ACCEPT_TIMEOUT_SEC 60 +#define ZoO_SERVER_SOCKET_LISTEN_BACKLOG 5 + +enum ZoO_server_thread_state +{ + ZoO_SERVER_JOINING_THREAD, + ZoO_SERVER_RUNNING_THREAD, + ZoO_SERVER_NO_THREAD +}; + +struct ZoO_server_thread_data +{ + pthread_t posix_id; + enum ZoO_server_thread_state state; +}; + +struct ZoO_server_thread_collection +{ + struct ZoO_server_thread_data * threads; + size_t threads_capacity; + pthread_mutex_t mutex; + pthread_barrier_t barrier; + ZoO_index currently_running; +}; + +struct ZoO_server_socket +{ + int file_descriptor; + fd_set as_a_set; + struct timeval timeout; +}; + +struct ZoO_server_thread_parameters +{ + struct ZoO_server_thread_collection * thread_collection; + const struct ZoO_parameters * server_params; + ZoO_index thread_id; + int socket; +}; + +struct ZoO_server_worker { - char type; - union - { - struct ZoO_pipe_names pipe_names; - ZoO_index pthread_id; - } data; + char * buffer; + size_t buffer_capacity; + size_t buffer_length; + struct ZoO_server_thread_parameters params; }; struct ZoO_server { - /* TODO: insert 2 thread barrier. */ - mqd_t mailbox; - ZoO_index running_threads; + struct ZoO_server_thread_collection workers; + struct ZoO_server_socket socket; + struct ZoO_server_thread_parameters thread_params; }; #endif diff --git a/src/server/server_wait_for_event.c b/src/server/server_wait_for_event.c new file mode 100644 index 0000000..b229e6b --- /dev/null +++ b/src/server/server_wait_for_event.c @@ -0,0 +1,53 @@ +#include <sys/select.h> + +#include <errno.h> +#include <stdio.h> +#include <string.h> + +#include "server.h" + +int ZoO_server_wait_for_event +( + struct ZoO_server server [const static 1] +) +{ + int ready_fds; + const int old_errno = errno; + + /* call to select may alter timeout */ + memset((void *) &(server->socket.timeout), 0, sizeof(struct timeval)); + + server->socket.timeout.tv_sec = ZoO_SERVER_SOCKET_ACCEPT_TIMEOUT_SEC; + + ready_fds = select + ( + (server->socket.file_descriptor + 1), + &(server->socket.as_a_set), + (fd_set *) NULL, + (fd_set *) NULL, + &(server->socket.timeout) + ); + + if (errno == EINTR) + { + ready_fds = 0; + } + + if (ready_fds == -1) + { + fprintf + ( + stderr, + "[F] Unable to wait on server socket: %s.\n", + strerror(errno) + ); + + errno = old_errno; + + return -1; + } + + errno = old_errno; + + return ready_fds; +} diff --git a/src/server/server_worker.c b/src/server/server_worker.c index 04f71ca..f6378e0 100644 --- a/src/server/server_worker.c +++ b/src/server/server_worker.c @@ -1,21 +1,62 @@ -#include "worker.h" +#include <signal.h> +#include <string.h> +#include <stdio.h> -void ZoO_worker_initialize_parameters +#include "server.h" + +static void initialize +( + struct ZoO_server_worker worker [const restrict static 1], + void * input +) +{ + memcpy + ( + (void *) &(worker->params), + (const void *) input, + sizeof(struct ZoO_server_thread_parameters) + ); + + pthread_barrier_wait(&(worker->params.thread_collection->barrier)); + + worker->buffer = (char *) NULL; + worker->buffer_capacity = 0; + worker->buffer_length = 0; +} + +static void finalize ( - struct ZoO_worker_parameters worker_params; - const struct ZoO_server_message msg_buffer [const restrict static 1], - const struct ZoO_parameters params [const restrict static 1] + struct ZoO_server_worker worker [const restrict static 1] ) { - worker_params->thread_id = 0; - pthread_barrier_t * barrier; - mqd_t * server_mailbox; - const struct ZoO_pipe_names * pipe_names; + pthread_mutex_lock(&(worker->params.thread_collection->mutex)); + + worker->params.thread_collection->threads[worker->params.thread_id].state = + ZoO_SERVER_JOINING_THREAD; + + pthread_mutex_unlock(&(worker->params.thread_collection->mutex)); +} + +void * ZoO_server_worker_main (void * input) +{ + struct ZoO_server_worker worker; + + initialize(&worker, input); + + while (ZoO_server_is_running()) + { + if (ZoO_server_worker_receive(&worker) < 0) + { + break; + } + + if (ZoO_server_worker_handle_request(&worker) < 0) + { + break; + } + } - /* Program data */ - ZoO_index markov_order; - struct ZoO_knowledge * k; - const char * storage_filename; + finalize(&worker); - /* TODO */ + return NULL; } diff --git a/src/server/server_worker.h b/src/server/server_worker.h deleted file mode 100644 index 825cc11..0000000 --- a/src/server/server_worker.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _ZoO_WORKER_WORKER_H_ -#define _ZoO_WORKER_WORKER_H_ - -#include "../parameters/parameters_types.h" - -#include "worker_types.h" - -#endif diff --git a/src/server/server_worker_handle_request.c b/src/server/server_worker_handle_request.c new file mode 100644 index 0000000..0c97091 --- /dev/null +++ b/src/server/server_worker_handle_request.c @@ -0,0 +1,11 @@ +#include "server.h" + +int ZoO_server_worker_handle_request +( + struct ZoO_server_worker worker [const restrict static 1] +) +{ + /* TODO */ + + return 0; +} diff --git a/src/server/server_worker_receive.c b/src/server/server_worker_receive.c new file mode 100644 index 0000000..6e70159 --- /dev/null +++ b/src/server/server_worker_receive.c @@ -0,0 +1,11 @@ +#include "server.h" + +int ZoO_server_worker_receive +( + struct ZoO_server_worker worker [const restrict static 1] +) +{ + /* TODO */ + + return 0; +} diff --git a/src/server/server_worker_types.h b/src/server/server_worker_types.h deleted file mode 100644 index 07757bd..0000000 --- a/src/server/server_worker_types.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _ZoO_WORKER_WORKER_TYPES_H_ -#define _ZoO_WORKER_WORKER_TYPES_H_ - -#include <mqueue.h> - -#include "../core/index_types.h" - -#include "../pipes/pipes_types.h" - -#include "../knowledge/knowledge_types.h" - - -struct ZoO_worker_parameters -{ - /* Communication data */ - ZoO_index thread_id; - pthread_barrier_t * barrier; - mqd_t * server_mailbox; - const struct ZoO_pipe_names * pipe_names; - - /* Program data */ - ZoO_index markov_order; - struct ZoO_knowledge * k; - const char * storage_filename; -}; - -#endif |


