Utility functions to test with threads Untested on Windows
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/0627cd45 Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/0627cd45 Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/0627cd45 Branch: refs/heads/master Commit: 0627cd454bd8bfbfa4a53a9c375c084b8033c075 Parents: 1368881 Author: Nick Wellnhofer <[email protected]> Authored: Sat May 9 23:50:28 2015 +0200 Committer: Nick Wellnhofer <[email protected]> Committed: Tue May 12 20:15:24 2015 +0200 ---------------------------------------------------------------------- runtime/core/Clownfish/TestHarness/TestUtils.c | 124 +++++++++++++++++++ .../core/Clownfish/TestHarness/TestUtils.cfh | 28 +++++ 2 files changed, 152 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0627cd45/runtime/core/Clownfish/TestHarness/TestUtils.c ---------------------------------------------------------------------- diff --git a/runtime/core/Clownfish/TestHarness/TestUtils.c b/runtime/core/Clownfish/TestHarness/TestUtils.c index a9614ed..3b695c9 100644 --- a/runtime/core/Clownfish/TestHarness/TestUtils.c +++ b/runtime/core/Clownfish/TestHarness/TestUtils.c @@ -24,6 +24,7 @@ #include "Clownfish/TestHarness/TestUtils.h" #include "Clownfish/CharBuf.h" +#include "Clownfish/Err.h" #include "Clownfish/String.h" #include "Clownfish/Util/Memory.h" @@ -116,4 +117,127 @@ TestUtils_get_str(const char *ptr) { return Str_new_from_utf8(ptr, strlen(ptr)); } +/********************************** Windows ********************************/ +#if !defined(CFISH_NOTHREADS) && defined(CHY_HAS_WINDOWS_H) + +#include <windows.h> + +struct Thread { + HANDLE handle; + thread_routine_t routine; + void *arg; +}; + +bool TestUtils_has_threads = true; + +static DWORD +S_thread(void *arg) { + Thread *thread = (Thread*)arg; + thread->routine(thread->arg); + return 0; +} + +Thread* +TestUtils_thread_create(thread_routine_t routine, void *arg) { + Thread *thread = (Thread*)MALLOCATE(sizeof(Thread)); + thread->routine = routine; + thread->arg = arg; + + thread->handle = CreateThread(NULL, 0, S_thread, thread, 0, NULL); + if (thread->handle == NULL) { + FREEMEM(thread); + THROW(ERR, "CreateThread failed: %s", Err_win_error()); + } + + return thread; +} + +void +TestUtils_thread_yield() { + SwitchToThread(); +} + +void +TestUtils_thread_join(Thread *thread) { + DWORD event = WaitForSingleObject(thread->handle, INFINITE); + FREEMEM(thread); + if (event != WAIT_OBJECT_0) { + THROW(ERR, "WaitForSingleObject failed: %s", Err_win_error()); + } +} + +/******************************** pthreads *********************************/ +#elif !defined(CFISH_NOTHREADS) && defined(CHY_HAS_PTHREAD_H) + +#include <pthread.h> + +struct Thread { + pthread_t pthread; + thread_routine_t routine; + void *arg; +}; + +bool TestUtils_has_threads = true; + +static void* +S_thread(void *arg) { + Thread *thread = (Thread*)arg; + thread->routine(thread->arg); + return NULL; +} + +Thread* +TestUtils_thread_create(thread_routine_t routine, void *arg) { + Thread *thread = (Thread*)MALLOCATE(sizeof(Thread)); + thread->routine = routine; + thread->arg = arg; + + int err = pthread_create(&thread->pthread, NULL, S_thread, thread); + if (err != 0) { + FREEMEM(thread); + THROW(ERR, "pthread_create failed: %s", strerror(err)); + } + + return thread; +} + +void +TestUtils_thread_yield() { + pthread_yield(); +} + +void +TestUtils_thread_join(Thread *thread) { + int err = pthread_join(thread->pthread, NULL); + FREEMEM(thread); + if (err != 0) { + THROW(ERR, "pthread_create failed: %s", strerror(err)); + } +} + +/**************************** No thread support ****************************/ +#else + +bool TestUtils_has_threads = false; + +Thread* +TestUtils_thread_create(thread_routine_t routine, void *arg) { + UNUSED_VAR(routine); + UNUSED_VAR(arg); + THROW(ERR, "No thread support"); + UNREACHABLE_RETURN(Thread*); +} + +void +TestUtils_thread_yield() { +} + +void +TestUtils_thread_join(Thread *thread) { + UNUSED_VAR(thread); + THROW(ERR, "No thread support"); +} + +#endif + http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0627cd45/runtime/core/Clownfish/TestHarness/TestUtils.cfh ---------------------------------------------------------------------- diff --git a/runtime/core/Clownfish/TestHarness/TestUtils.cfh b/runtime/core/Clownfish/TestHarness/TestUtils.cfh index 4107189..6614d06 100644 --- a/runtime/core/Clownfish/TestHarness/TestUtils.cfh +++ b/runtime/core/Clownfish/TestHarness/TestUtils.cfh @@ -16,8 +16,18 @@ parcel Clownfish; +__C__ + +typedef void (*cfish_thread_routine_t)(void *arg); + +typedef struct cfish_Thread cfish_Thread; + +__END_C__ + inert class Clownfish::TestHarness::TestUtils { + inert bool has_threads; + /** Testing-only String factory which uses strlen(). */ inert incremented String* @@ -60,6 +70,24 @@ inert class Clownfish::TestHarness::TestUtils { */ inert incremented String* random_string(size_t length); + + inert cfish_Thread* + thread_create(cfish_thread_routine_t routine, void *arg); + + inert void + thread_yield(); + + inert void + thread_join(cfish_Thread *thread); } +__C__ + +#ifdef CFISH_USE_SHORT_NAMES + #define Thread cfish_Thread + #define thread_routine_t cfish_thread_routine_t +#endif + +__END_C__ +
