more packages to implement better thread interface.

This commit is contained in:
Vitor Santos Costa 2010-07-23 15:54:13 +01:00
parent eebff5df6a
commit f3b9811ef7
5 changed files with 77 additions and 40 deletions

View File

@ -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_CreateModule,(Atom));
X_API Term STD_PROTO(YAP_StripModule,(Term, Term *)); X_API Term STD_PROTO(YAP_StripModule,(Term, Term *));
X_API int STD_PROTO(YAP_ThreadSelf,(void)); X_API int STD_PROTO(YAP_ThreadSelf,(void));
X_API int STD_PROTO(YAP_GetThreadRefCount,(int)); X_API int STD_PROTO(YAP_ThreadCreateEngine,(struct thread_attr_struct *));
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_ThreadAttachEngine,(int)); X_API int STD_PROTO(YAP_ThreadAttachEngine,(int));
X_API int STD_PROTO(YAP_ThreadDetachEngine,(int)); X_API int STD_PROTO(YAP_ThreadDetachEngine,(int));
X_API int STD_PROTO(YAP_ThreadDestroyEngine,(int)); X_API int STD_PROTO(YAP_ThreadDestroyEngine,(int));
@ -2836,22 +2834,22 @@ YAP_ThreadSelf(void)
#if THREADS #if THREADS
return Yap_thread_self(); return Yap_thread_self();
#else #else
return 0; return NULL;
#endif
}
X_API CELL
YAP_ThreadCreateEngine(struct thread_attr_struct *attr)
{
#if THREADS
return Yap_thread_create_engine(attr);
#else
return FALSE;
#endif #endif
} }
X_API int 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 #if THREADS
return Yap_thread_attach_engine(wid); return Yap_thread_attach_engine(wid);

View File

@ -264,6 +264,7 @@ p_create_thread(void)
/* make sure we can proceed */ /* make sure we can proceed */
if (!init_thread_engine(new_worker_id, ssize, tsize, sysize, &ARG1, &ARG5, &ARG6)) if (!init_thread_engine(new_worker_id, ssize, tsize, sysize, &ARG1, &ARG5, &ARG6))
return FALSE; return FALSE;
FOREIGN_ThreadHandle(new_worker_id).pthread_handle = NULL;
FOREIGN_ThreadHandle(new_worker_id).id = new_worker_id; FOREIGN_ThreadHandle(new_worker_id).id = new_worker_id;
FOREIGN_ThreadHandle(new_worker_id).ref_count = 1; 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) { 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) { if (new_id == -1) {
/* YAP ERROR */ /* YAP ERROR */
return FALSE; return -1;
} }
if (ops == NULL) { if (ops == NULL) {
ops = &opsv; ops = &opsv;
@ -392,9 +393,9 @@ Yap_thread_create_engine(thread_attr *ops)
pthread_mutex_lock(&(FOREIGN_ThreadHandle(0).tlock)); pthread_mutex_lock(&(FOREIGN_ThreadHandle(0).tlock));
} }
if (!init_thread_engine(new_id, ops->ssize, ops->tsize, ops->sysize, &t, &t, &(ops->egoal))) 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).id = new_id;
FOREIGN_ThreadHandle(new_id).pthread_handle = pthread_self();
FOREIGN_ThreadHandle(new_id).ref_count = 0; FOREIGN_ThreadHandle(new_id).ref_count = 0;
setup_engine(new_id); setup_engine(new_id);
if (pthread_self() != Yap_master_thread) { if (pthread_self() != Yap_master_thread) {
@ -410,8 +411,10 @@ Yap_thread_attach_engine(int wid)
pthread_mutex_lock(&(FOREIGN_ThreadHandle(wid).tlock)); pthread_mutex_lock(&(FOREIGN_ThreadHandle(wid).tlock));
if (FOREIGN_ThreadHandle(wid).ref_count ) { if (FOREIGN_ThreadHandle(wid).ref_count ) {
DEBUG_TLOCK_ACCESS(8, wid); DEBUG_TLOCK_ACCESS(8, wid);
FOREIGN_ThreadHandle(wid).ref_count++;
FOREIGN_ThreadHandle(wid).pthread_handle = pthread_self();
pthread_mutex_unlock(&(FOREIGN_ThreadHandle(wid).tlock)); pthread_mutex_unlock(&(FOREIGN_ThreadHandle(wid).tlock));
return FALSE; return TRUE;
} }
FOREIGN_ThreadHandle(wid).pthread_handle = pthread_self(); FOREIGN_ThreadHandle(wid).pthread_handle = pthread_self();
FOREIGN_ThreadHandle(wid).ref_count++; FOREIGN_ThreadHandle(wid).ref_count++;
@ -426,6 +429,12 @@ Yap_thread_detach_engine(int wid)
{ {
DEBUG_TLOCK_ACCESS(10, wid); DEBUG_TLOCK_ACCESS(10, wid);
pthread_mutex_lock(&(FOREIGN_ThreadHandle(wid).tlock)); 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--; FOREIGN_ThreadHandle(wid).ref_count--;
DEBUG_TLOCK_ACCESS(11, wid); DEBUG_TLOCK_ACCESS(11, wid);
pthread_mutex_unlock(&(FOREIGN_ThreadHandle(wid).tlock)); pthread_mutex_unlock(&(FOREIGN_ThreadHandle(wid).tlock));
@ -435,6 +444,8 @@ Yap_thread_detach_engine(int wid)
Int Int
Yap_thread_destroy_engine(int wid) 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) { if (FOREIGN_ThreadHandle(wid).ref_count == 0) {
kill_thread_engine(wid, TRUE); kill_thread_engine(wid, TRUE);
return TRUE; return TRUE;

View File

@ -231,7 +231,8 @@ typedef void *PL_engine_t;
#define BUF_RING 0x0100 #define BUF_RING 0x0100
#define BUF_MALLOC 0x0200 #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_SET 0 /* engine set successfully */
#define PL_ENGINE_INVAL 2 /* engine doesn't exist */ #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 void PL_load_extensions(const PL_extension *);
extern X_API int PL_handle_signals(void); extern X_API int PL_handle_signals(void);
extern X_API int PL_thread_self(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_attach_engine(const PL_thread_attr_t *);
extern X_API int PL_thread_destroy_engine(void); extern X_API int PL_thread_destroy_engine(void);
extern X_API int PL_thread_at_exit(void (*)(void *), void *, int); extern X_API int PL_thread_at_exit(void (*)(void *), void *, int);

View File

@ -468,11 +468,11 @@ extern X_API YAP_agc_hook PROTO(YAP_AGCRegisterHook,(YAP_agc_hook));
extern X_API char * PROTO(YAP_cwd,(void)); extern X_API char * PROTO(YAP_cwd,(void));
/* thread stuff */ /* thread stuff */
extern X_API int PROTO(YAP_ThreadSelf,(void)); 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_ThreadCreateEngine,(YAP_thread_attr *));
extern X_API int PROTO(YAP_ThreadAttachEngine,(int)); extern X_API int PROTO(YAP_ThreadAttachEngine,(int));
extern X_API int PROTO(YAP_ThreadDetachEngine,(int)); extern X_API int PROTO(YAP_ThreadDetachEngine,(int));
extern X_API int PROTO(YAP_ThreadDestroyEngine,(int)); extern X_API int PROTO(YAP_ThreadDestroyEngine,(int));
/* blob stuff */ /* blob stuff */
extern X_API YAP_Term PROTO(YAP_MkBlobTerm,(unsigned int)); extern X_API YAP_Term PROTO(YAP_MkBlobTerm,(unsigned int));

View File

@ -2778,12 +2778,25 @@ X_API int PL_is_inf(term_t st)
X_API int PL_thread_self(void) 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) 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) { if (wid < 0) {
/* we do not have an engine */ /* 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; return -1;
} else { } else {
/* attach myself again */ /* attach myself again */
YAP_ThreadAttachEngine(wid); return YAP_ThreadAttachEngine(wid);
return wid;
} }
} }
X_API int PL_thread_destroy_engine(void) X_API int PL_thread_destroy_engine(void)
{ {
int wid = YAP_ThreadSelf(); int wid = PL_thread_self();
if (wid < 0) { if (wid < 0) {
/* we do not have an engine */ /* 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.tsize = attr->global_size;
yapt.alias = (YAP_Term)attr->alias; yapt.alias = (YAP_Term)attr->alias;
yapt.cancel = attr->cancel; yapt.cancel = attr->cancel;
return (PL_engine_t)YAP_ThreadCreateEngine(&yapt); return Yap_WLocal+YAP_ThreadCreateEngine(&yapt);
} else { } 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 X_API int
PL_destroy_engine(PL_engine_t e) 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 X_API int
PL_set_engine(PL_engine_t engine, PL_engine_t *old) PL_set_engine(PL_engine_t engine, PL_engine_t *old)
{ {
YAP_Int cwid = YAP_ThreadSelf(); int cwid = PL_thread_self(), nwid;
if (old) {
if (*old) *old = (PL_engine_t)cwid; 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; 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; return PL_ENGINE_INVAL;
if (!(YAP_ThreadAttachEngine((YAP_Int)engine))) {
return PL_ENGINE_INUSE;
} }
return PL_ENGINE_SET; return PL_ENGINE_SET;
} }