From f3b9811ef78832da1e672b54f96f16f64b1d6815 Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Fri, 23 Jul 2010 15:54:13 +0100 Subject: [PATCH] more packages to implement better thread interface. --- C/c_interface.c | 28 +++++++++----------- C/threads.c | 19 ++++++++++--- include/SWI-Prolog.h | 4 ++- include/YapInterface.h | 10 +++---- library/yap2swi/yap2swi.c | 56 ++++++++++++++++++++++++++++----------- 5 files changed, 77 insertions(+), 40 deletions(-) diff --git a/C/c_interface.c b/C/c_interface.c index 7d2f59fed..1e6ec443f 100755 --- a/C/c_interface.c +++ b/C/c_interface.c @@ -493,9 +493,7 @@ X_API Term STD_PROTO(YAP_CurrentModule,(void)); X_API Term STD_PROTO(YAP_CreateModule,(Atom)); X_API Term STD_PROTO(YAP_StripModule,(Term, Term *)); X_API int STD_PROTO(YAP_ThreadSelf,(void)); -X_API int STD_PROTO(YAP_GetThreadRefCount,(int)); -X_API void STD_PROTO(YAP_SetThreadRefCount,(int,int)); -X_API CELL STD_PROTO(YAP_ThreadCreateEngine,(struct thread_attr_struct *)); +X_API int STD_PROTO(YAP_ThreadCreateEngine,(struct thread_attr_struct *)); X_API int STD_PROTO(YAP_ThreadAttachEngine,(int)); X_API int STD_PROTO(YAP_ThreadDetachEngine,(int)); X_API int STD_PROTO(YAP_ThreadDestroyEngine,(int)); @@ -2836,22 +2834,22 @@ YAP_ThreadSelf(void) #if THREADS return Yap_thread_self(); #else - return 0; -#endif -} - -X_API CELL -YAP_ThreadCreateEngine(struct thread_attr_struct *attr) -{ -#if THREADS - return Yap_thread_create_engine(attr); -#else - return FALSE; + return NULL; #endif } X_API int -YAP_ThreadAttachEngine(int wid) +YAP_ThreadCreateEngine(struct thread_attr_struct * attr) +{ +#if THREADS + return Yap_thread_create_engine(attr); +#else + return -1; +#endif +} + +X_API int +YAP_ThreadAttachEngine( int wid) { #if THREADS return Yap_thread_attach_engine(wid); diff --git a/C/threads.c b/C/threads.c index e1134b6a5..5da6e5f42 100755 --- a/C/threads.c +++ b/C/threads.c @@ -264,6 +264,7 @@ p_create_thread(void) /* make sure we can proceed */ if (!init_thread_engine(new_worker_id, ssize, tsize, sysize, &ARG1, &ARG5, &ARG6)) return FALSE; + FOREIGN_ThreadHandle(new_worker_id).pthread_handle = NULL; FOREIGN_ThreadHandle(new_worker_id).id = new_worker_id; FOREIGN_ThreadHandle(new_worker_id).ref_count = 1; if ((FOREIGN_ThreadHandle(new_worker_id).ret = pthread_create(&FOREIGN_ThreadHandle(new_worker_id).pthread_handle, NULL, thread_run, (void *)(&(FOREIGN_ThreadHandle(new_worker_id).id)))) == 0) { @@ -377,7 +378,7 @@ Yap_thread_create_engine(thread_attr *ops) */ if (new_id == -1) { /* YAP ERROR */ - return FALSE; + return -1; } if (ops == NULL) { ops = &opsv; @@ -392,9 +393,9 @@ Yap_thread_create_engine(thread_attr *ops) pthread_mutex_lock(&(FOREIGN_ThreadHandle(0).tlock)); } if (!init_thread_engine(new_id, ops->ssize, ops->tsize, ops->sysize, &t, &t, &(ops->egoal))) - return FALSE; + return -1; + FOREIGN_ThreadHandle(new_id).pthread_handle = NULL; FOREIGN_ThreadHandle(new_id).id = new_id; - FOREIGN_ThreadHandle(new_id).pthread_handle = pthread_self(); FOREIGN_ThreadHandle(new_id).ref_count = 0; setup_engine(new_id); if (pthread_self() != Yap_master_thread) { @@ -410,8 +411,10 @@ Yap_thread_attach_engine(int wid) pthread_mutex_lock(&(FOREIGN_ThreadHandle(wid).tlock)); if (FOREIGN_ThreadHandle(wid).ref_count ) { DEBUG_TLOCK_ACCESS(8, wid); + FOREIGN_ThreadHandle(wid).ref_count++; + FOREIGN_ThreadHandle(wid).pthread_handle = pthread_self(); pthread_mutex_unlock(&(FOREIGN_ThreadHandle(wid).tlock)); - return FALSE; + return TRUE; } FOREIGN_ThreadHandle(wid).pthread_handle = pthread_self(); FOREIGN_ThreadHandle(wid).ref_count++; @@ -426,6 +429,12 @@ Yap_thread_detach_engine(int wid) { DEBUG_TLOCK_ACCESS(10, wid); pthread_mutex_lock(&(FOREIGN_ThreadHandle(wid).tlock)); + if (FOREIGN_ThreadHandle(wid).ref_count == 0) { + FOREIGN_ThreadHandle(wid).pthread_handle = NULL; + DEBUG_TLOCK_ACCESS(11, wid); + pthread_mutex_unlock(&(FOREIGN_ThreadHandle(wid).tlock)); + return FALSE; + } FOREIGN_ThreadHandle(wid).ref_count--; DEBUG_TLOCK_ACCESS(11, wid); pthread_mutex_unlock(&(FOREIGN_ThreadHandle(wid).tlock)); @@ -435,6 +444,8 @@ Yap_thread_detach_engine(int wid) Int Yap_thread_destroy_engine(int wid) { + DEBUG_TLOCK_ACCESS(10, wid); + pthread_mutex_lock(&(FOREIGN_ThreadHandle(wid).tlock)); if (FOREIGN_ThreadHandle(wid).ref_count == 0) { kill_thread_engine(wid, TRUE); return TRUE; diff --git a/include/SWI-Prolog.h b/include/SWI-Prolog.h index 4abeaf44e..b5ef74982 100755 --- a/include/SWI-Prolog.h +++ b/include/SWI-Prolog.h @@ -231,7 +231,8 @@ typedef void *PL_engine_t; #define BUF_RING 0x0100 #define BUF_MALLOC 0x0200 -#define PL_ENGINE_CURRENT ((PL_engine_t)-1) +#define PL_ENGINE_MAIN ((PL_engine_t)0x1) +#define PL_ENGINE_CURRENT ((PL_engine_t)0x2) #define PL_ENGINE_SET 0 /* engine set successfully */ #define PL_ENGINE_INVAL 2 /* engine doesn't exist */ @@ -494,6 +495,7 @@ extern X_API void PL_register_extensions(const PL_extension *); extern X_API void PL_load_extensions(const PL_extension *); extern X_API int PL_handle_signals(void); extern X_API int PL_thread_self(void); +extern X_API int PL_unify_thread_id(term_t, int); extern X_API int PL_thread_attach_engine(const PL_thread_attr_t *); extern X_API int PL_thread_destroy_engine(void); extern X_API int PL_thread_at_exit(void (*)(void *), void *, int); diff --git a/include/YapInterface.h b/include/YapInterface.h index 0e703e1f5..2d06302f5 100755 --- a/include/YapInterface.h +++ b/include/YapInterface.h @@ -468,11 +468,11 @@ extern X_API YAP_agc_hook PROTO(YAP_AGCRegisterHook,(YAP_agc_hook)); extern X_API char * PROTO(YAP_cwd,(void)); /* thread stuff */ -extern X_API int PROTO(YAP_ThreadSelf,(void)); -extern X_API YAP_CELL PROTO(YAP_ThreadCreateEngine,(YAP_thread_attr *)); -extern X_API int PROTO(YAP_ThreadAttachEngine,(int)); -extern X_API int PROTO(YAP_ThreadDetachEngine,(int)); -extern X_API int PROTO(YAP_ThreadDestroyEngine,(int)); +extern X_API int PROTO(YAP_ThreadSelf,(void)); +extern X_API int PROTO(YAP_ThreadCreateEngine,(YAP_thread_attr *)); +extern X_API int PROTO(YAP_ThreadAttachEngine,(int)); +extern X_API int PROTO(YAP_ThreadDetachEngine,(int)); +extern X_API int PROTO(YAP_ThreadDestroyEngine,(int)); /* blob stuff */ extern X_API YAP_Term PROTO(YAP_MkBlobTerm,(unsigned int)); diff --git a/library/yap2swi/yap2swi.c b/library/yap2swi/yap2swi.c index 47448cc2d..3f6968794 100755 --- a/library/yap2swi/yap2swi.c +++ b/library/yap2swi/yap2swi.c @@ -2778,12 +2778,25 @@ X_API int PL_is_inf(term_t st) X_API int PL_thread_self(void) { - return YAP_ThreadSelf(); +#if THREADS + if (pthread_getspecific(Yap_yaamregs_key) == NULL) + return -1; + return worker_id; +#else + return -2; +#endif } +X_API int PL_unify_thread_id(term_t t, int i) +{ + Term iterm = MkIntegerTerm(i); + return Yap_unify(Yap_GetFromSlot(t),iterm); +} + + X_API int PL_thread_attach_engine(const PL_thread_attr_t *attr) { - int wid = YAP_ThreadSelf(); + int wid = PL_thread_self(); if (wid < 0) { /* we do not have an engine */ @@ -2807,14 +2820,13 @@ X_API int PL_thread_attach_engine(const PL_thread_attr_t *attr) return -1; } else { /* attach myself again */ - YAP_ThreadAttachEngine(wid); - return wid; + return YAP_ThreadAttachEngine(wid); } } X_API int PL_thread_destroy_engine(void) { - int wid = YAP_ThreadSelf(); + int wid = PL_thread_self(); if (wid < 0) { /* we do not have an engine */ @@ -2843,9 +2855,9 @@ PL_create_engine(const PL_thread_attr_t *attr) yapt.tsize = attr->global_size; yapt.alias = (YAP_Term)attr->alias; yapt.cancel = attr->cancel; - return (PL_engine_t)YAP_ThreadCreateEngine(&yapt); + return Yap_WLocal+YAP_ThreadCreateEngine(&yapt); } else { - return (PL_engine_t)YAP_ThreadCreateEngine(NULL); + return Yap_WLocal+YAP_ThreadCreateEngine(NULL); } } @@ -2853,22 +2865,36 @@ PL_create_engine(const PL_thread_attr_t *attr) X_API int PL_destroy_engine(PL_engine_t e) { - return YAP_ThreadDestroyEngine((YAP_Int)e); + return YAP_ThreadDestroyEngine((struct worker_local *)e-Yap_WLocal); } X_API int PL_set_engine(PL_engine_t engine, PL_engine_t *old) { - YAP_Int cwid = YAP_ThreadSelf(); - if (old) { - if (*old) *old = (PL_engine_t)cwid; + int cwid = PL_thread_self(), nwid; + + if (cwid >= 0) { + if (old) *old = (PL_engine_t)(Yap_WLocal+cwid); } - if (engine == PL_ENGINE_CURRENT) + if (engine == PL_ENGINE_MAIN) { + nwid = 0; + } else if (engine == PL_ENGINE_CURRENT) { + if (cwid < 0) + return PL_ENGINE_INVAL; return PL_ENGINE_SET; - if (engine < 0) /* should really check if engine does not exist */ + } + if (FOREIGN_ThreadHandle(nwid).pthread_handle) { + if (cwid != nwid) + return PL_ENGINE_INUSE; + return PL_ENGINE_SET; + } + if (cwid) { + if (!YAP_ThreadDetachEngine(nwid)) { + return PL_ENGINE_INVAL; + } + } + if (!YAP_ThreadAttachEngine(nwid)) { return PL_ENGINE_INVAL; - if (!(YAP_ThreadAttachEngine((YAP_Int)engine))) { - return PL_ENGINE_INUSE; } return PL_ENGINE_SET; }