aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2017-06-29 15:20:24 +0200
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2017-06-29 15:20:24 +0200
commit8d5c996aef28fae9f848e1fab419b4d2821e8862 (patch)
treea2b5fac4ee5b3e21711fe80c273f300541d16844
parentf7c5db9a32bb0082b59e73fa01656cd083756c3d (diff)
downloadmarkov-k-ram-8d5c996aef28fae9f848e1fab419b4d2821e8862.zip
markov-k-ram-8d5c996aef28fae9f848e1fab419b4d2821e8862.tar.bz2
First shot at finer mutexes.
-rw-r--r--src/knowledge/CMakeLists.txt1
-rw-r--r--src/knowledge/knowledge.c108
-rw-r--r--src/knowledge/knowledge.h117
-rw-r--r--src/knowledge/knowledge_finalize.c5
-rw-r--r--src/knowledge/knowledge_get_random_sequence.c19
-rw-r--r--src/knowledge/knowledge_get_random_target.c54
-rw-r--r--src/knowledge/knowledge_learn_markov_sequence.c62
-rw-r--r--src/knowledge/knowledge_learn_sequence.c3
-rw-r--r--src/knowledge/knowledge_learn_word.c79
-rw-r--r--src/knowledge/knowledge_locks.c342
-rw-r--r--src/knowledge/knowledge_swt_tws_modifications.c20
-rw-r--r--src/knowledge/knowledge_types.h8
-rw-r--r--src/sequence/sequence_creation.c45
-rw-r--r--src/sequence/sequence_from_string.c6
-rw-r--r--src/sequence/sequence_to_string.c4
-rw-r--r--src/server/server_worker_handle_request.c74
16 files changed, 714 insertions, 233 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;
diff --git a/src/sequence/sequence_creation.c b/src/sequence/sequence_creation.c
index 0b5e393..2e8e17e 100644
--- a/src/sequence/sequence_creation.c
+++ b/src/sequence/sequence_creation.c
@@ -45,10 +45,10 @@ static int extend_left
{
JH_index sequence_id, word_id;
- (void) JH_knowledge_lock_access(k, io);
-
/* preceding_words_weights_sum > 0 */
+ JH_knowledge_readlock_sequences(k, io);
+
if
(
JH_knowledge_find_sequence
@@ -60,16 +60,14 @@ static int extend_left
) < 0
)
{
- (void) JH_knowledge_unlock_access(k, io);
+ JH_knowledge_readunlock_sequences(k, io);
JH_S_ERROR(io, "Could not find matching TWS sequence.");
return -1;
}
- (void) JH_knowledge_unlock_access(k, io);
-
- (void) JH_knowledge_lock_access(k, io);
+ JH_knowledge_readunlock_sequences(k, io);
if
(
@@ -78,19 +76,16 @@ static int extend_left
k,
&word_id,
(*sequence)[0],
- sequence_id
+ sequence_id,
+ io
) < 0
)
{
- (void) JH_knowledge_unlock_access(k, io);
-
JH_S_ERROR(io, "Could not find matching TWS target.");
return -1;
}
- (void) JH_knowledge_unlock_access(k, io);
-
if
(
JH_sequence_append_left
@@ -243,10 +238,10 @@ static int extend_right
{
JH_index sequence_id, word_id;
- (void) JH_knowledge_lock_access(k, io);
-
/* preceding_words_weights_sum > 0 */
+ JH_knowledge_readlock_sequences(k, io);
+
if
(
JH_knowledge_find_sequence
@@ -258,7 +253,7 @@ static int extend_right
) < 0
)
{
- (void) JH_knowledge_unlock_access(k, io);
+ JH_knowledge_readunlock_sequences(k, io);
JH_S_PROG_ERROR
(
@@ -270,9 +265,7 @@ static int extend_right
return -1;
}
- (void) JH_knowledge_unlock_access(k, io);
-
- (void) JH_knowledge_lock_access(k, io);
+ JH_knowledge_readunlock_sequences(k, io);
if
(
@@ -281,12 +274,11 @@ static int extend_right
k,
sequence_id,
(*sequence)[*sequence_length - 1],
- &word_id
+ &word_id,
+ io
) < 0
)
{
- (void) JH_knowledge_unlock_access(k, io);
-
JH_S_PROG_ERROR
(
io,
@@ -297,9 +289,6 @@ static int extend_right
return -1;
}
- (void) JH_knowledge_unlock_access(k, io);
-
-
/* following_words_weights_sum > 0 */
if
@@ -314,13 +303,9 @@ static int extend_right
) < 0
)
{
- (void) JH_knowledge_unlock_access(k, io);
-
return -3;
}
- (void) JH_knowledge_unlock_access(k, io);
-
return 0;
}
@@ -454,8 +439,6 @@ static int initialize_sequence
{
sequence[(markov_order - 1)] = initial_word;
- (void) JH_knowledge_lock_access(k, io);
-
if
(
JH_knowledge_copy_random_swt_sequence
@@ -468,13 +451,9 @@ static int initialize_sequence
) < 0
)
{
- (void) JH_knowledge_unlock_access(k, io);
-
return -1;
}
- (void) JH_knowledge_unlock_access(k, io);
-
if (JH_DEBUG_SEQUENCE_CREATION_INIT)
{
JH_index i;
diff --git a/src/sequence/sequence_from_string.c b/src/sequence/sequence_from_string.c
index 5b92943..5e434f3 100644
--- a/src/sequence/sequence_from_string.c
+++ b/src/sequence/sequence_from_string.c
@@ -30,8 +30,6 @@ static int add_word_to_sequence
{
JH_index word_id;
- (void) JH_knowledge_lock_access(k, io);
-
if
(
JH_knowledge_learn_word
@@ -44,13 +42,9 @@ static int add_word_to_sequence
) < 0
)
{
- (void) JH_knowledge_unlock_access(k, io);
-
return -1;
}
- (void) JH_knowledge_unlock_access(k, io);
-
if
(
JH_sequence_append_right
diff --git a/src/sequence/sequence_to_string.c b/src/sequence/sequence_to_string.c
index 6794fcb..70dcf1a 100644
--- a/src/sequence/sequence_to_string.c
+++ b/src/sequence/sequence_to_string.c
@@ -114,9 +114,7 @@ static int add_word
return 0;
}
- (void) JH_knowledge_lock_access(k, io);
- JH_knowledge_get_word(k, word_id, &word, &word_size);
- (void) JH_knowledge_unlock_access(k, io);
+ JH_knowledge_get_word(k, word_id, &word, &word_size, io);
insertion_point = *destination_length;
diff --git a/src/server/server_worker_handle_request.c b/src/server/server_worker_handle_request.c
index 256ed06..25f93bc 100644
--- a/src/server/server_worker_handle_request.c
+++ b/src/server/server_worker_handle_request.c
@@ -19,44 +19,22 @@ static int load_reply
if
(
- JH_knowledge_lock_access
- (
- worker->params.knowledge,
- worker->socket_as_file
- ) < 0
- )
- {
- return -1;
- }
-
- if
- (
JH_knowledge_rarest_word
(
worker->params.knowledge,
worker->sequence_buffer,
worker->sequence_buffer_length,
- &rarest_word_id
+ &rarest_word_id,
+ worker->socket_as_file
) < 0
)
{
- JH_knowledge_unlock_access
- (
- worker->params.knowledge,
- worker->socket_as_file
- );
JH_S_ERROR(worker->socket_as_file, "Could not find rarest word.");
return -1;
}
- JH_knowledge_unlock_access
- (
- worker->params.knowledge,
- worker->socket_as_file
- );
-
JH_DEBUG
(
worker->socket_as_file,
@@ -162,18 +140,6 @@ static int handle_rl
if
(
- JH_knowledge_lock_access
- (
- worker->params.knowledge,
- worker->socket_as_file
- ) < 0
- )
- {
- return JH_server_worker_send_negative(worker);
- }
-
- if
- (
JH_knowledge_learn_sequence
(
worker->params.knowledge,
@@ -184,21 +150,9 @@ static int handle_rl
) < 0
)
{
- JH_knowledge_unlock_access
- (
- worker->params.knowledge,
- worker->socket_as_file
- );
-
return JH_server_worker_send_negative(worker);
}
- JH_knowledge_unlock_access
- (
- worker->params.knowledge,
- worker->socket_as_file
- );
-
return JH_server_worker_send_positive(worker);
}
@@ -226,18 +180,6 @@ static int handle_rlr
if
(
- JH_knowledge_lock_access
- (
- worker->params.knowledge,
- worker->socket_as_file
- ) < 0
- )
- {
- return JH_server_worker_send_negative(worker);
- }
-
- if
- (
JH_knowledge_learn_sequence
(
worker->params.knowledge,
@@ -248,21 +190,9 @@ static int handle_rlr
) < 0
)
{
- JH_knowledge_unlock_access
- (
- worker->params.knowledge,
- worker->socket_as_file
- );
-
return JH_server_worker_send_negative(worker);
}
- JH_knowledge_unlock_access
- (
- worker->params.knowledge,
- worker->socket_as_file
- );
-
if (load_reply(worker) < 0)
{
return JH_server_worker_send_negative(worker);