Changes have been pushed for the project "Fawkes Robotics Software Framework".
Gitweb: http://git.fawkesrobotics.org/fawkes.git Trac: http://trac.fawkesrobotics.org The branch, thofmann/syncpoint has been updated discards f5fdae0464a9f9d8e9bf0115e13022d673e98c93 (commit) discards e13afae91e7b287a223176a27fba95f58feea9cd (commit) to 66ffcb4f319aa95b9be40b08ea04eb93adadc6f8 (commit) via a813cad9808a342105f3d4c09e19d45a32f43d98 (commit) via 45b469c013a83ff6368e6a61618bb3a78a7c08f5 (commit) This update added new revisions after undoing existing revisions. That is to say, the old revision is not a strict subset of the new revision. This situation occurs when you --force push a change and generate a repository containing something like this: * -- * -- B -- O -- O -- O (f5fdae0464a9f9d8e9bf0115e13022d673e98c93) \ N -- N -- N (66ffcb4f319aa95b9be40b08ea04eb93adadc6f8) When this happens we assume that you've already had alert emails for all of the O revisions, and so we here report only the revisions in the N branch from the common base, B. http://git.fawkesrobotics.org/fawkes.git/thofmann/syncpoint Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - *Log* --------------------------------------------------------------- commit 45b469c013a83ff6368e6a61618bb3a78a7c08f5 Author: Till Hofmann <hofm...@kbsg.rwth-aachen.de> AuthorDate: Tue May 20 11:31:45 2014 +0200 Commit: Till Hofmann <hofm...@kbsg.rwth-aachen.de> CommitDate: Tue May 20 12:39:29 2014 +0200 syncpoint: throw exception if a waiting component calls wait() again http://git.fawkesrobotics.org/fawkes.git/commit/45b469c http://trac.fawkesrobotics.org/changeset/45b469c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - commit a813cad9808a342105f3d4c09e19d45a32f43d98 Author: Till Hofmann <hofm...@kbsg.rwth-aachen.de> AuthorDate: Tue May 20 11:42:47 2014 +0200 Commit: Till Hofmann <hofm...@kbsg.rwth-aachen.de> CommitDate: Tue May 20 12:39:30 2014 +0200 syncpoint: add unit tests for multiple wait calls, multi-threading http://git.fawkesrobotics.org/fawkes.git/commit/a813cad http://trac.fawkesrobotics.org/changeset/a813cad - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - commit 66ffcb4f319aa95b9be40b08ea04eb93adadc6f8 Author: Till Hofmann <hofm...@kbsg.rwth-aachen.de> AuthorDate: Tue May 20 14:40:22 2014 +0200 Commit: Till Hofmann <hofm...@kbsg.rwth-aachen.de> CommitDate: Tue May 20 14:40:22 2014 +0200 syncpoint: add unit tests to test wait/emit calls with multi-threading http://git.fawkesrobotics.org/fawkes.git/commit/66ffcb4 http://trac.fawkesrobotics.org/changeset/66ffcb4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *Summary* ----------------------------------------------------------- src/libs/syncpoint/syncpoint.cpp | 1 + src/libs/syncpoint/tests/test_syncpoint.cpp | 53 +++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 0 deletions(-) - *Diffs* ------------------------------------------------------------- - *commit* 45b469c013a83ff6368e6a61618bb3a78a7c08f5 - - - - - - - - - - Author: Till Hofmann <hofm...@kbsg.rwth-aachen.de> Date: Tue May 20 11:31:45 2014 +0200 Subject: syncpoint: throw exception if a waiting component calls wait() again src/libs/syncpoint/exceptions.h | 18 ++++++++++++++++++ src/libs/syncpoint/syncpoint.cpp | 7 +++++++ src/libs/syncpoint/syncpoint.h | 1 + 3 files changed, 26 insertions(+), 0 deletions(-) _Diff for modified files_: diff --git a/src/libs/syncpoint/exceptions.h b/src/libs/syncpoint/exceptions.h index ef3e633..a1bf769 100644 --- a/src/libs/syncpoint/exceptions.h +++ b/src/libs/syncpoint/exceptions.h @@ -153,6 +153,24 @@ class SyncPointInvalidComponentException : public Exception } }; +/** A component called wait() but is already waiting + * + */ +class SyncPointMultipleWaitCallsException : public Exception +{ + public: + /** Constructor. + * @param component The calling component + * @param identifier The identifier of the SyncPoint + */ + SyncPointMultipleWaitCallsException(const char * component, + const char * identifier) + { + append("Component '%s' called wait() on SyncPoint '%s', but is already waiting", + component, identifier); + } +}; + } // namespace fawkes diff --git a/src/libs/syncpoint/syncpoint.cpp b/src/libs/syncpoint/syncpoint.cpp index d0b815d..927ec66 100644 --- a/src/libs/syncpoint/syncpoint.cpp +++ b/src/libs/syncpoint/syncpoint.cpp @@ -111,6 +111,7 @@ SyncPoint::emit(const char * component) mutex->unlock(); throw SyncPointNonWatcherCalledEmitException(component, get_identifier()); } + waiting_watchers.clear(); wait_condition->wake_all(); mutex->unlock(); } @@ -126,6 +127,12 @@ SyncPoint::wait(const char * component) { mutex->unlock(); throw SyncPointNonWatcherCalledWaitException(component, get_identifier()); } + // check if calling component is not already waiting + if (waiting_watchers.count(component)) { + mutex->unlock(); + throw SyncPointMultipleWaitCallsException(component, get_identifier()); + } + waiting_watchers.insert(component); wait_condition->wait(); mutex->unlock(); } diff --git a/src/libs/syncpoint/syncpoint.h b/src/libs/syncpoint/syncpoint.h index efa7067..8fe3707 100644 --- a/src/libs/syncpoint/syncpoint.h +++ b/src/libs/syncpoint/syncpoint.h @@ -60,6 +60,7 @@ class SyncPoint private: const char * identifier_; std::set<const char *> watchers; + std::set<const char *> waiting_watchers; Mutex *mutex; WaitCondition *wait_condition; - *commit* a813cad9808a342105f3d4c09e19d45a32f43d98 - - - - - - - - - - Author: Till Hofmann <hofm...@kbsg.rwth-aachen.de> Date: Tue May 20 11:42:47 2014 +0200 Subject: syncpoint: add unit tests for multiple wait calls, multi-threading src/libs/syncpoint/tests/test_syncpoint.cpp | 59 +++++++++++++++++++++++++++ 1 files changed, 59 insertions(+), 0 deletions(-) _Diff for modified files_: diff --git a/src/libs/syncpoint/tests/test_syncpoint.cpp b/src/libs/syncpoint/tests/test_syncpoint.cpp index bafcd8c..33cbafb 100644 --- a/src/libs/syncpoint/tests/test_syncpoint.cpp +++ b/src/libs/syncpoint/tests/test_syncpoint.cpp @@ -30,6 +30,8 @@ #include <pthread.h> #include <baseapp/run.h> +#include <unistd.h> + #include <set> using namespace fawkes; @@ -177,3 +179,60 @@ TEST_F(SyncPointManagerTest, SyncPointManagerExceptions) { } + +// helper function used for testing wait() +void * call_wait(void *data) +{ + SyncPoint * sp = (SyncPoint *)(data); + sp->wait("component"); + return NULL; +} + +TEST_F(SyncPointManagerTest, MultipleWaits) +{ + RefPtr<SyncPoint> sp_ref = manager->get_syncpoint("component", "/test/sp1"); + SyncPoint * sp = *sp_ref; + pthread_t thread1; + pthread_create(&thread1, NULL, call_wait, (void *)sp); + // make sure the other thread is first + usleep(100); + ASSERT_THROW(sp_ref->wait("component"), SyncPointMultipleWaitCallsException); + pthread_cancel(thread1); +} + +/** struct used for multithreading tests */ +struct waiter_thread_params { + /** SyncPointManager passed to the thread */ + RefPtr<SyncPointManager> manager; + /** Thread number */ + uint thread_nr; +}; + +/** get a SyncPoint and wait for it */ +void * start_waiter_thread(void * data) { + waiter_thread_params *params = (waiter_thread_params *)data; + char component[40]; + sprintf(component, "component %u", params->thread_nr); + RefPtr<SyncPoint> sp = params->manager->get_syncpoint(component, "/test/sp1"); + sp->wait(component); + return NULL; +} + +TEST_F(SyncPointManagerTest, ParallelWaitCalls) +{ + uint num_threads = 100; + pthread_t threads[num_threads]; + waiter_thread_params *params[num_threads]; + for (uint i = 0; i < num_threads; i++) { + params[i] = new waiter_thread_params(); + params[i]->manager = manager; + params[i]->thread_nr = i; + pthread_create(&threads[i], NULL, start_waiter_thread, params[i]); + } + + usleep(100); + for (uint i = 0; i < num_threads; i++) { + pthread_cancel(threads[i]); + delete params[i]; + } +} - *commit* 66ffcb4f319aa95b9be40b08ea04eb93adadc6f8 - - - - - - - - - - Author: Till Hofmann <hofm...@kbsg.rwth-aachen.de> Date: Tue May 20 14:40:22 2014 +0200 Subject: syncpoint: add unit tests to test wait/emit calls with multi-threading src/libs/syncpoint/tests/test_syncpoint.cpp | 53 +++++++++++++++++++++++++++ 1 files changed, 53 insertions(+), 0 deletions(-) _Diff for modified files_: diff --git a/src/libs/syncpoint/tests/test_syncpoint.cpp b/src/libs/syncpoint/tests/test_syncpoint.cpp index 33cbafb..8a3ddb6 100644 --- a/src/libs/syncpoint/tests/test_syncpoint.cpp +++ b/src/libs/syncpoint/tests/test_syncpoint.cpp @@ -31,6 +31,7 @@ #include <baseapp/run.h> #include <unistd.h> +#include <time.h> #include <set> @@ -200,6 +201,7 @@ TEST_F(SyncPointManagerTest, MultipleWaits) pthread_cancel(thread1); } + /** struct used for multithreading tests */ struct waiter_thread_params { /** SyncPointManager passed to the thread */ @@ -236,3 +238,54 @@ TEST_F(SyncPointManagerTest, ParallelWaitCalls) delete params[i]; } } + +/** start multiple threads, let them wait for a SyncPoint, + * emit the SyncPoint and verify that they all returned + */ +TEST_F(SyncPointManagerTest, ParallelWaitsReturn) +{ + uint num_threads = 100; + pthread_t threads[num_threads]; + waiter_thread_params *params[num_threads]; + for (uint i = 0; i < num_threads; i++) { + params[i] = new waiter_thread_params(); + params[i]->manager = manager; + params[i]->thread_nr = i; + pthread_create(&threads[i], NULL, start_waiter_thread, params[i]); + } + + usleep(50); + RefPtr<SyncPoint> sp =manager->get_syncpoint("main_thread", "/test/sp1"); + + sp->emit("main_thread"); + usleep(500); + for (uint i = 0; i < num_threads; i++) { + ASSERT_EQ(0, pthread_tryjoin_np(threads[i], NULL)); + delete params[i]; + } +} + +/** start multiple threads, let them wait for a SyncPoint, + * but don't emit the SyncPoint. Verify that they have not returned + */ +TEST_F(SyncPointManagerTest, WaitDoesNotReturnImmediately) +{ + uint num_threads = 100; + pthread_t threads[num_threads]; + waiter_thread_params *params[num_threads]; + for (uint i = 0; i < num_threads; i++) { + params[i] = new waiter_thread_params(); + params[i]->manager = manager; + params[i]->thread_nr = i; + pthread_create(&threads[i], NULL, start_waiter_thread, params[i]); + } + + usleep(50); + RefPtr<SyncPoint> sp =manager->get_syncpoint("main_thread", "/test/sp1"); + usleep(500); + + for (uint i = 0; i < num_threads; i++) { + ASSERT_EQ(16, pthread_tryjoin_np(threads[i], NULL)); + delete params[i]; + } +} -- Fawkes Robotics Framework http://www.fawkesrobotics.org _______________________________________________ fawkes-commits mailing list fawkes-commits@lists.kbsg.rwth-aachen.de https://lists.kbsg.rwth-aachen.de/listinfo/fawkes-commits