| summaryrefslogtreecommitdiff |
diff options
Diffstat (limited to 'src/knowledge')
| -rw-r--r-- | src/knowledge/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/knowledge/knowledge.c | 108 | ||||
| -rw-r--r-- | src/knowledge/knowledge.h | 117 | ||||
| -rw-r--r-- | src/knowledge/knowledge_finalize.c | 5 | ||||
| -rw-r--r-- | src/knowledge/knowledge_get_random_sequence.c | 19 | ||||
| -rw-r--r-- | src/knowledge/knowledge_get_random_target.c | 54 | ||||
| -rw-r--r-- | src/knowledge/knowledge_learn_markov_sequence.c | 62 | ||||
| -rw-r--r-- | src/knowledge/knowledge_learn_sequence.c | 3 | ||||
| -rw-r--r-- | src/knowledge/knowledge_learn_word.c | 79 | ||||
| -rw-r--r-- | src/knowledge/knowledge_locks.c | 342 | ||||
| -rw-r--r-- | src/knowledge/knowledge_swt_tws_modifications.c | 20 | ||||
| -rw-r--r-- | src/knowledge/knowledge_types.h | 8 |
12 files changed, 699 insertions, 119 deletions
diff --git a/src/knowledge/CMakeLists.txt b/src/knowledge/CMakeLists.txt index ba3293d..ab96392 100644 --- a/src/knowledge/CMakeLists.txt +++ b/src/knowledge/CMakeLists.txt @@ -7,6 +7,7 @@ set( ${CMAKE_CURRENT_SOURCE_DIR}/knowledge_learn_markov_sequence.c ${CMAKE_CURRENT_SOURCE_DIR}/knowledge_learn_sequence.c ${CMAKE_CURRENT_SOURCE_DIR}/knowledge_learn_word.c + ${CMAKE_CURRENT_SOURCE_DIR}/knowledge_locks.c ${CMAKE_CURRENT_SOURCE_DIR}/knowledge_search.c ${CMAKE_CURRENT_SOURCE_DIR}/knowledge_swt_tws_modifications.c ) diff --git a/src/knowledge/knowledge.c b/src/knowledge/knowledge.c index 93351da..9ef9c6e 100644 --- a/src/knowledge/knowledge.c +++ b/src/knowledge/knowledge.c @@ -24,9 +24,36 @@ int JH_knowledge_initialize (struct JH_knowledge k [const restrict static 1]) k->sequences_sorted = (JH_index *) NULL; #ifndef JH_RUNNING_FRAMA_C - error = pthread_mutex_init(&(k->mutex), (const pthread_mutexattr_t *) NULL); + error = + pthread_rwlock_init + ( + &(k->words_lock), + (const pthread_rwlockattr_t *) NULL + ); +#else + error = 0; +#endif + + if (error != 0) + { + JH_FATAL + ( + stderr, + "Unable to initialize knowledge's words lock: %s.", + strerror(error) + ); + + return -1; + } + +#ifndef JH_RUNNING_FRAMA_C + error = + pthread_rwlock_init + ( + &(k->sequences_lock), + (const pthread_rwlockattr_t *) NULL + ); #else - k->mutex = 1; error = 0; #endif @@ -35,7 +62,7 @@ int JH_knowledge_initialize (struct JH_knowledge k [const restrict static 1]) JH_FATAL ( stderr, - "Unable to initialize knowledge mutex: %s.", + "Unable to initialize knowledge's sequences lock: %s.", strerror(error) ); @@ -75,82 +102,30 @@ int JH_knowledge_initialize (struct JH_knowledge k [const restrict static 1]) return 0; } -int JH_knowledge_lock_access -( - struct JH_knowledge k [const restrict static 1], - FILE io [const restrict static 1] -) -{ - int err; - -#ifndef JH_RUNNING_FRAMA_C - err = pthread_mutex_lock(&(k->mutex)); -#else - /*@ assert (k->mutex == 1); @*/ - k->mutex = 0; - err = 0; -#endif - - if (err != 0) - { - JH_ERROR - ( - io, - "Unable to get exclusive access to knowledge: %s", - strerror(err) - ); - - return -1; - } - - return 0; -} - -void JH_knowledge_unlock_access -( - struct JH_knowledge k [const restrict static 1], - FILE io [const restrict static 1] -) -{ - int err; - -#ifndef JH_RUNNING_FRAMA_C - err = pthread_mutex_unlock(&(k->mutex)); -#else - /*@ assert (k->mutex == 0); @*/ - k->mutex = 1; - err = 0; -#endif - - if (err != 0) - { - JH_ERROR - ( - io, - "Unable to release exclusive access to knowledge: %s", - strerror(err) - ); - } -} - void JH_knowledge_get_word ( - const struct JH_knowledge k [const static 1], + struct JH_knowledge k [const static 1], const JH_index word_ref, const JH_char * word [const restrict static 1], - JH_index word_length [const restrict static 1] + JH_index word_length [const restrict static 1], + FILE io [const restrict static 1] ) { + JH_knowledge_readlock_words(k, io); + *word = k->words[word_ref].word; *word_length = k->words[word_ref].word_length; + + JH_knowledge_readunlock_words(k, io); } int JH_knowledge_rarest_word ( - const struct JH_knowledge k [const static 1], + struct JH_knowledge k [const static 1], const JH_index sequence [const restrict static 1], const size_t sequence_length, - JH_index word_id [const restrict static 1] + JH_index word_id [const restrict static 1], + FILE io [const restrict static 1] ) { JH_index current_max_score; @@ -163,6 +138,7 @@ int JH_knowledge_rarest_word for (i = 0; i < sequence_length; ++i) { + JH_knowledge_readlock_word(k, sequence[i], io); if ( (k->words[sequence[i]].occurrences <= current_max_score) @@ -174,6 +150,8 @@ int JH_knowledge_rarest_word *word_id = sequence[i]; success = 0; } + + JH_knowledge_readunlock_word(k, sequence[i], io); } return success; diff --git a/src/knowledge/knowledge.h b/src/knowledge/knowledge.h index 20293bc..fc4c5bc 100644 --- a/src/knowledge/knowledge.h +++ b/src/knowledge/knowledge.h @@ -8,43 +8,77 @@ #include "knowledge_types.h" -/*@ - requires \valid(k); - requires \separated(k, io); +int JH_knowledge_readlock_words +( + struct JH_knowledge k [const restrict static 1], + FILE io [const restrict static 1] +); -// Do not use if lock is already yours. - requires (k->mutex == 1); +int JH_knowledge_writelock_words +( + struct JH_knowledge k [const restrict static 1], + FILE io [const restrict static 1] +); -// Returns zero on success, -1 on failure. - assigns \result; - ensures ((\result == 0) || (\result == -1)); +int JH_knowledge_readunlock_words +( + struct JH_knowledge k [const restrict static 1], + FILE io [const restrict static 1] +); -// On success, lock is acquired. - ensures ((\result == 0) ==> (k->mutex == 0)); +int JH_knowledge_writeunlock_words +( + struct JH_knowledge k [const restrict static 1], + FILE io [const restrict static 1] +); -// Changes the status of the lock. - assigns (k->mutex); -@*/ -int JH_knowledge_lock_access +int JH_knowledge_readlock_word ( struct JH_knowledge k [const restrict static 1], + const JH_index i, FILE io [const restrict static 1] ); -/*@ - requires \valid(k); - requires \separated(k, io); +int JH_knowledge_writelock_word +( + struct JH_knowledge k [const restrict static 1], + const JH_index i, + FILE io [const restrict static 1] +); -// Do not use if lock is not yours. - requires (k->mutex == 0); +int JH_knowledge_readunlock_word +( + struct JH_knowledge k [const restrict static 1], + const JH_index i, + FILE io [const restrict static 1] +); -// Lock is released. - ensures (k->mutex == 1); +int JH_knowledge_writeunlock_word +( + struct JH_knowledge k [const restrict static 1], + const JH_index i, + FILE io [const restrict static 1] +); -// Changes the status of the lock. - assigns (k->mutex); -@*/ -void JH_knowledge_unlock_access +int JH_knowledge_readlock_sequences +( + struct JH_knowledge k [const restrict static 1], + FILE io [const restrict static 1] +); + +int JH_knowledge_writelock_sequences +( + struct JH_knowledge k [const restrict static 1], + FILE io [const restrict static 1] +); + +int JH_knowledge_readunlock_sequences +( + struct JH_knowledge k [const restrict static 1], + FILE io [const restrict static 1] +); + +int JH_knowledge_writeunlock_sequences ( struct JH_knowledge k [const restrict static 1], FILE io [const restrict static 1] @@ -112,10 +146,11 @@ int JH_knowledge_learn_markov_sequence void JH_knowledge_get_word ( - const struct JH_knowledge k [const static 1], + struct JH_knowledge k [const static 1], const JH_index word_ref, const JH_char * word [const restrict static 1], - JH_index word_length [const restrict static 1] + JH_index word_length [const restrict static 1], + FILE io [const restrict static 1] ); /* @@ -127,6 +162,8 @@ void JH_knowledge_get_word * {word} is not in {k}. * {*result} is where {word} was expected to be found in * {k->sorted_indices}. + * + * Does not acquire locks */ int JH_knowledge_find_word_id ( @@ -136,6 +173,9 @@ int JH_knowledge_find_word_id JH_index result [const restrict static 1] ); + /* + * Does not acquire locks + */ int JH_knowledge_find_sequence ( const struct JH_knowledge k [const static 1], @@ -146,12 +186,16 @@ int JH_knowledge_find_sequence int JH_knowledge_rarest_word ( - const struct JH_knowledge k [const static 1], + struct JH_knowledge k [const static 1], const JH_index sequence [const restrict static 1], const size_t sequence_length, - JH_index word_id [const restrict static 1] + JH_index word_id [const restrict static 1], + FILE io [const restrict static 1] ); +/* +* Does not acquire locks +*/ int JH_knowledge_find_markov_sequence ( const JH_index sequence_id, @@ -159,6 +203,9 @@ int JH_knowledge_find_markov_sequence JH_index result [const restrict static 1] ); +/* +* Does not acquire locks +*/ int JH_knowledge_find_sequence_target ( const JH_index target_id, @@ -168,23 +215,25 @@ int JH_knowledge_find_sequence_target int JH_knowledge_random_tws_target ( - const struct JH_knowledge k [const static 1], + struct JH_knowledge k [const static 1], JH_index target [const restrict static 1], const JH_index word_id, - const JH_index sequence_id + const JH_index sequence_id, + FILE io [const restrict static 1] ); int JH_knowledge_random_swt_target ( - const struct JH_knowledge k [const static 1], + struct JH_knowledge k [const static 1], const JH_index sequence_id, const JH_index word_id, - JH_index target [const restrict static 1] + JH_index target [const restrict static 1], + FILE io [const restrict static 1] ); int JH_knowledge_copy_random_swt_sequence ( - const struct JH_knowledge k [const static 1], + struct JH_knowledge k [const static 1], JH_index sequence [const restrict static 1], const JH_index word_id, const JH_index markov_order, diff --git a/src/knowledge/knowledge_finalize.c b/src/knowledge/knowledge_finalize.c index 8020b9a..0665e59 100644 --- a/src/knowledge/knowledge_finalize.c +++ b/src/knowledge/knowledge_finalize.c @@ -69,6 +69,8 @@ static void knowledge_word_finalize knowledge_sequence_collection_finalize(&(w->swt)); knowledge_sequence_collection_finalize(&(w->tws)); + + pthread_rwlock_destroy(&(w->lock)); } /* See: "knowledge.h" */ @@ -118,5 +120,6 @@ void JH_knowledge_finalize (struct JH_knowledge k [const restrict static 1]) k->sequences_sorted = (JH_index *) NULL; } - pthread_mutex_destroy(&(k->mutex)); + pthread_rwlock_destroy(&(k->words_lock)); + pthread_rwlock_destroy(&(k->sequences_lock)); } diff --git a/src/knowledge/knowledge_get_random_sequence.c b/src/knowledge/knowledge_get_random_sequence.c index 60a075f..5a214fd 100644 --- a/src/knowledge/knowledge_get_random_sequence.c +++ b/src/knowledge/knowledge_get_random_sequence.c @@ -49,7 +49,7 @@ static int weighted_random_pick int JH_knowledge_copy_random_swt_sequence ( - const struct JH_knowledge k [const static 1], + struct JH_knowledge k [const static 1], JH_index sequence [const restrict static 1], const JH_index word_id, const JH_index markov_order, @@ -58,6 +58,8 @@ int JH_knowledge_copy_random_swt_sequence { JH_index sequence_id; + JH_knowledge_readlock_word(k, word_id, io); + if ( weighted_random_pick @@ -65,7 +67,8 @@ int JH_knowledge_copy_random_swt_sequence &(k->words[word_id].swt), k->words[word_id].occurrences, &sequence_id - ) < 0 + ) + < 0 ) { JH_S_PROG_ERROR @@ -73,11 +76,17 @@ int JH_knowledge_copy_random_swt_sequence io, "Knowledge inconsistency; there are no acceptable markov sequences " "linked to a word that has been picked as being an acceptable pillar." - ) - ; + ); + + JH_knowledge_readunlock_word(k, word_id, io); + return -1; } + JH_knowledge_readunlock_word(k, word_id, io); + + JH_knowledge_readlock_sequences(k, io); + memcpy ( (void *) sequence, @@ -85,5 +94,7 @@ int JH_knowledge_copy_random_swt_sequence (((size_t) (markov_order - 1)) * sizeof(JH_index)) ); + JH_knowledge_readunlock_sequences(k, io); + return 0; } diff --git a/src/knowledge/knowledge_get_random_target.c b/src/knowledge/knowledge_get_random_target.c index d5f321d..1e878cf 100644 --- a/src/knowledge/knowledge_get_random_target.c +++ b/src/knowledge/knowledge_get_random_target.c @@ -48,14 +48,17 @@ static int weighted_random_pick int JH_knowledge_random_tws_target ( - const struct JH_knowledge k [const static 1], + struct JH_knowledge k [const static 1], JH_index target [const restrict static 1], const JH_index word_id, - const JH_index sequence_id + const JH_index sequence_id, + FILE io [const restrict static 1] ) { JH_index s_index; + JH_knowledge_readlock_word(k, word_id, io); + if ( JH_knowledge_find_markov_sequence @@ -66,27 +69,46 @@ int JH_knowledge_random_tws_target ) < 0 ) { + JH_knowledge_readunlock_word(k, word_id, io); + return -1; } - return + if + ( weighted_random_pick ( &(k->words[word_id].tws.sequences_ref[s_index]), target - ); + ) + < 0 + ) + { + JH_knowledge_readunlock_word(k, word_id, io); + + return -1; + } + else + { + JH_knowledge_readunlock_word(k, word_id, io); + + return 0; + } } int JH_knowledge_random_swt_target ( - const struct JH_knowledge k [const static 1], + struct JH_knowledge k [const static 1], const JH_index sequence_id, const JH_index word_id, - JH_index target [const restrict static 1] + JH_index target [const restrict static 1], + FILE io [const restrict static 1] ) { JH_index s_index; + JH_knowledge_readlock_word(k, word_id, io); + if ( JH_knowledge_find_markov_sequence @@ -97,13 +119,29 @@ int JH_knowledge_random_swt_target ) < 0 ) { + JH_knowledge_readunlock_word(k, word_id, io); + return -1; } - return + if + ( weighted_random_pick ( &(k->words[word_id].swt.sequences_ref[s_index]), target - ); + ) + < 0 + ) + { + JH_knowledge_readunlock_word(k, word_id, io); + + return -1; + } + else + { + JH_knowledge_readunlock_word(k, word_id, io); + + return 0; + } } diff --git a/src/knowledge/knowledge_learn_markov_sequence.c b/src/knowledge/knowledge_learn_markov_sequence.c index 4a770e2..74e29a7 100644 --- a/src/knowledge/knowledge_learn_markov_sequence.c +++ b/src/knowledge/knowledge_learn_markov_sequence.c @@ -380,6 +380,8 @@ int JH_knowledge_learn_markov_sequence } } + JH_knowledge_readlock_sequences(k, io); + if ( JH_knowledge_find_sequence @@ -388,9 +390,49 @@ int JH_knowledge_learn_markov_sequence sequence, markov_order, sequence_id - ) == 0 + ) + == 0 ) { + JH_knowledge_readunlock_sequences(k, io); + + JH_DEBUG + ( + io, + JH_DEBUG_KNOWLEDGE_LEARN_SEQUENCE, + "Markov sequence is known. ID: %u", + *sequence_id + ); + + return 0; + } + + /* + * We need to write, but we currently have reading access. + * We can't get the writing access while someone (even us) has the reading + * access, so we release the reading access. + */ + JH_knowledge_readunlock_sequences(k, io); + + JH_knowledge_writelock_sequences(k, io); + /* + * Now we have writer access, but someone else might have modified 'k' before + * we did, so we need to find the sequence's location again. + */ + if + ( + JH_knowledge_find_sequence + ( + k, + sequence, + markov_order, + sequence_id + ) + == 0 + ) + { + JH_knowledge_writeunlock_sequences(k, io); + JH_DEBUG ( io, @@ -405,7 +447,8 @@ int JH_knowledge_learn_markov_sequence sorted_id = *sequence_id; *sequence_id = k->sequences_length; - return + if + ( add_sequence ( k, @@ -414,5 +457,18 @@ int JH_knowledge_learn_markov_sequence *sequence_id, sorted_id, io - ); + ) + < 0 + ) + { + JH_knowledge_writeunlock_sequences(k, io); + + return -1; + } + else + { + JH_knowledge_writeunlock_sequences(k, io); + + return 0; + } } diff --git a/src/knowledge/knowledge_learn_sequence.c b/src/knowledge/knowledge_learn_sequence.c index 90dbc88..9502f2e 100644 --- a/src/knowledge/knowledge_learn_sequence.c +++ b/src/knowledge/knowledge_learn_sequence.c @@ -256,8 +256,11 @@ int JH_knowledge_learn_sequence return -1; } + JH_knowledge_writelock_word(k, sequence[i], io); k->words[sequence[i]].occurrences += 1; + + JH_knowledge_writeunlock_word(k, sequence[i], io); } return 0; diff --git a/src/knowledge/knowledge_learn_word.c b/src/knowledge/knowledge_learn_word.c index 1389cdb..9320f10 100644 --- a/src/knowledge/knowledge_learn_word.c +++ b/src/knowledge/knowledge_learn_word.c @@ -20,17 +20,40 @@ static void initialize_sequence_collection c->sequences_ref_sorted = (JH_index *) NULL; } -static void initialize_word +static int initialize_word ( struct JH_knowledge_word w [const restrict static 1] ) { + int error; + w->word = (const JH_char *) NULL; w->word_length = 0; w->occurrences = 0; initialize_sequence_collection(&(w->swt)); initialize_sequence_collection(&(w->tws)); + + error = + pthread_rwlock_init + ( + &(w->lock), + (const pthread_rwlockattr_t *) NULL + ); + + if (error != 0) + { + JH_ERROR + ( + stderr, + "Unable to initialize a knowledge's word lock: %s.", + strerror(error) + ); + + return -1; + } + + return 0; } /******************************************************************************/ @@ -269,6 +292,45 @@ int JH_knowledge_learn_word return -1; } + JH_knowledge_readlock_words(k, io); + + if + ( + JH_knowledge_find_word_id + ( + k, + word, + (((size_t) word_length) * sizeof(JH_char)), + word_id + ) == 0 + ) + { + JH_knowledge_readunlock_words(k, io); + + JH_DEBUG + ( + io, + JH_DEBUG_KNOWLEDGE_LEARN_WORD, + "Word of size %u is already known (id: %u).", + (JH_index) word_length, + *word_id + ); + + return 0; + } + + /* + * We need to write, but we currently have reading access. + * We can't get the writing access while someone (even us) has the reading + * access, so we release the reading access. + */ + JH_knowledge_readunlock_words(k, io); + + JH_knowledge_writelock_words(k, io); + /* + * Now we have writer access, but someone else might have modified 'k' before + * we did, so we need to find the word's location again. + */ if ( JH_knowledge_find_word_id @@ -280,6 +342,8 @@ int JH_knowledge_learn_word ) == 0 ) { + JH_knowledge_writeunlock_words(k, io); + JH_DEBUG ( io, @@ -305,5 +369,16 @@ int JH_knowledge_learn_word sorted_id ); - return add_word(k, word, (JH_index) word_length, *word_id, sorted_id, io); + if (add_word(k, word, (JH_index) word_length, *word_id, sorted_id, io) < 0) + { + JH_knowledge_writeunlock_words(k, io); + + return -1; + } + else + { + JH_knowledge_writeunlock_words(k, io); + + return 0; + } } diff --git a/src/knowledge/knowledge_locks.c b/src/knowledge/knowledge_locks.c new file mode 100644 index 0000000..8d83664 --- /dev/null +++ b/src/knowledge/knowledge_locks.c @@ -0,0 +1,342 @@ +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <stdint.h> /* defines SIZE_MAX */ + +#include "../error/error.h" + +#include "knowledge.h" + +/** WORDS *********************************************************************/ +/**** LOCK ********************************************************************/ +int JH_knowledge_readlock_words +( + struct JH_knowledge k [const restrict static 1], + FILE io [const restrict static 1] +) +{ + int err; + + err = pthread_rwlock_rdlock(&(k->words_lock)); + + if (err != 0) + { + JH_ERROR + ( + io, + "Unable to gain read access to knowledge's words: %s", + strerror(err) + ); + + return -1; + } + + return 0; +} + +int JH_knowledge_writelock_words +( + struct JH_knowledge k [const restrict static 1], + FILE io [const restrict static 1] +) +{ + int err; + + err = pthread_rwlock_wrlock(&(k->words_lock)); + + if (err != 0) + { + JH_ERROR + ( + io, + "Unable to gain write access to knowledge's words: %s", + strerror(err) + ); + + return -1; + } + + return 0; +} + +/**** UNLOCK ******************************************************************/ +int JH_knowledge_readunlock_words +( + struct JH_knowledge k [const restrict static 1], + FILE io [const restrict static 1] +) +{ + int err; + + err = pthread_rwlock_unlock(&(k->words_lock)); + + if (err != 0) + { + JH_ERROR + ( + io, + "Unable to release read access to knowledge's words: %s", + strerror(err) + ); + + return -1; + } + + return 0; +} + +int JH_knowledge_writeunlock_words +( + struct JH_knowledge k [const restrict static 1], + FILE io [const restrict static 1] +) +{ + int err; + + err = pthread_rwlock_unlock(&(k->words_lock)); + + if (err != 0) + { + JH_ERROR + ( + io, + "Unable to release write access to knowledge's words: %s", + strerror(err) + ); + + return -1; + } + + return 0; +} + +/** SEQUENCES *****************************************************************/ +/**** LOCK ********************************************************************/ +int JH_knowledge_readlock_sequences +( + struct JH_knowledge k [const restrict static 1], + FILE io [const restrict static 1] +) +{ + int err; + + err = pthread_rwlock_rdlock(&(k->sequences_lock)); + + if (err != 0) + { + JH_ERROR + ( + io, + "Unable to gain read access to knowledge's sequences: %s", + strerror(err) + ); + + return -1; + } + + return 0; +} + +int JH_knowledge_writelock_sequences +( + struct JH_knowledge k [const restrict static 1], + FILE io [const restrict static 1] +) +{ + int err; + + err = pthread_rwlock_wrlock(&(k->sequences_lock)); + + if (err != 0) + { + JH_ERROR + ( + io, + "Unable to gain write access to knowledge's sequences: %s", + strerror(err) + ); + + return -1; + } + + return 0; +} + +/**** UNLOCK ******************************************************************/ +int JH_knowledge_readunlock_sequences +( + struct JH_knowledge k [const restrict static 1], + FILE io [const restrict static 1] +) +{ + int err; + + err = pthread_rwlock_unlock(&(k->sequences_lock)); + + if (err != 0) + { + JH_ERROR + ( + io, + "Unable to release read access to knowledge's sequences: %s", + strerror(err) + ); + + return -1; + } + + return 0; +} + +int JH_knowledge_writeunlock_sequences +( + struct JH_knowledge k [const restrict static 1], + FILE io [const restrict static 1] +) +{ + int err; + + err = pthread_rwlock_unlock(&(k->sequences_lock)); + + if (err != 0) + { + JH_ERROR + ( + io, + "Unable to release write access to knowledge's sequences: %s", + strerror(err) + ); + + return -1; + } + + return 0; +} + +/** WORD **********************************************************************/ +/**** LOCK ********************************************************************/ +int JH_knowledge_readlock_word +( + struct JH_knowledge k [const restrict static 1], + const JH_index i, + FILE io [const restrict static 1] +) +{ + int err; + + if (JH_knowledge_readlock_words(k, io) < 0) + { + return -1; + } + + err = pthread_rwlock_rdlock(&(k->words[i].lock)); + + if (err != 0) + { + JH_ERROR + ( + io, + "Unable to gain read access to a knowledge's word: %s", + strerror(err) + ); + + return -1; + } + + return 0; +} + +int JH_knowledge_writelock_word +( + struct JH_knowledge k [const restrict static 1], + const JH_index i, + FILE io [const restrict static 1] +) +{ + int err; + + if (JH_knowledge_readlock_words(k, io) < 0) + { + return -1; + } + + + err = pthread_rwlock_wrlock(&(k->words[i].lock)); + + if (err != 0) + { + JH_ERROR + ( + io, + "Unable to gain write access to a knowledge's word: %s", + strerror(err) + ); + + return -1; + } + + return 0; +} + +/**** UNLOCK ******************************************************************/ +int JH_knowledge_readunlock_word +( + struct JH_knowledge k [const restrict static 1], + const JH_index i, + FILE io [const restrict static 1] +) +{ + int err; + + if (JH_knowledge_readunlock_words(k, io) < 0) + { + return -1; + } + + err = pthread_rwlock_unlock(&(k->words[i].lock)); + + if (err != 0) + { + JH_ERROR + ( + io, + "Unable to release read access to a knowledge's word: %s", + strerror(err) + ); + + return -1; + } + + return 0; +} + +int JH_knowledge_writeunlock_word +( + struct JH_knowledge k [const restrict static 1], + const JH_index i, + FILE io [const restrict static 1] +) +{ + int err; + + if (JH_knowledge_readunlock_words(k, io) < 0) + { + return -1; + } + + err = pthread_rwlock_unlock(&(k->words[i].lock)); + + if (err != 0) + { + JH_ERROR + ( + io, + "Unable to release write access to a knowledge's word: %s", + strerror(err) + ); + + return -1; + } + + return 0; +} diff --git a/src/knowledge/knowledge_swt_tws_modifications.c b/src/knowledge/knowledge_swt_tws_modifications.c index 2acd093..cc8a938 100644 --- a/src/knowledge/knowledge_swt_tws_modifications.c +++ b/src/knowledge/knowledge_swt_tws_modifications.c @@ -163,6 +163,8 @@ int JH_knowledge_strengthen_swt { JH_index s_index, t_index; + JH_knowledge_writelock_word(k, word_id, io); + if ( JH_knowledge_find_markov_sequence @@ -184,6 +186,8 @@ int JH_knowledge_strengthen_swt ) < 0 ) { + JH_knowledge_writeunlock_word(k, word_id, io); + return -1; } } @@ -210,6 +214,8 @@ int JH_knowledge_strengthen_swt ) < 0 ) { + JH_knowledge_writeunlock_word(k, word_id, io); + return -1; } } @@ -233,12 +239,16 @@ int JH_knowledge_strengthen_swt "[W] Unable to strengthen SWT link: link is already at max strength." ); + JH_knowledge_writeunlock_word(k, word_id, io); + return 1; } k->words[word_id].swt.sequences_ref[s_index].occurrences += 1; k->words[word_id].swt.sequences_ref[s_index].targets[t_index].occurrences += 1; + JH_knowledge_writeunlock_word(k, word_id, io); + return 0; } @@ -253,6 +263,8 @@ int JH_knowledge_strengthen_tws { JH_index s_index, t_index; + JH_knowledge_writelock_word(k, word_id, io); + if ( JH_knowledge_find_markov_sequence @@ -274,6 +286,8 @@ int JH_knowledge_strengthen_tws ) < 0 ) { + JH_knowledge_writeunlock_word(k, word_id, io); + return -1; } } @@ -300,6 +314,8 @@ int JH_knowledge_strengthen_tws ) < 0 ) { + JH_knowledge_writeunlock_word(k, word_id, io); + return -1; } } @@ -323,11 +339,15 @@ int JH_knowledge_strengthen_tws "[E] Unable to strengthen TWS link: link is already at max strength." ); + JH_knowledge_writeunlock_word(k, word_id, io); + return -1; } k->words[word_id].tws.sequences_ref[s_index].occurrences += 1; k->words[word_id].tws.sequences_ref[s_index].targets[t_index].occurrences += 1; + JH_knowledge_writeunlock_word(k, word_id, io); + return 0; } diff --git a/src/knowledge/knowledge_types.h b/src/knowledge/knowledge_types.h index 82073ff..780d4df 100644 --- a/src/knowledge/knowledge_types.h +++ b/src/knowledge/knowledge_types.h @@ -40,14 +40,18 @@ struct JH_knowledge_word /* [Target] [Word] [Sequence] */ struct JH_knowledge_sequence_collection tws; + + pthread_rwlock_t lock; }; struct JH_knowledge { #ifndef JH_RUNNING_FRAMA_C - pthread_mutex_t mutex; + pthread_rwlock_t words_lock; + pthread_rwlock_t sequences_lock; #else - int mutex; + int words_lock; + int sequences_lock; #endif struct JH_knowledge_word * words; |


