| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | /*************************************************************************
 | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |  *									 * | 
					
						
							|  |  |  |  *	 YAP Prolog 							 * | 
					
						
							|  |  |  |  *									 * | 
					
						
							|  |  |  |  *	Yap Prolog was developed at NCCUP - Universidade do Porto	 * | 
					
						
							|  |  |  |  *									 * | 
					
						
							|  |  |  |  * Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997	 * | 
					
						
							|  |  |  |  *									 * | 
					
						
							|  |  |  |  ************************************************************************** | 
					
						
							|  |  |  |  *									 * | 
					
						
							|  |  |  |  * File:		stdpreds.c						 * | 
					
						
							|  |  |  |  * Last rev:								 * | 
					
						
							|  |  |  |  * mods:									 * | 
					
						
							|  |  |  |  * comments:	threads							 * | 
					
						
							|  |  |  |  *									 * | 
					
						
							|  |  |  |  *************************************************************************/ | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | #ifdef SCCS
 | 
					
						
							|  |  |  | static char     SccsId[] = "%W% %G%"; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |    @ingroup Threads  | 
					
						
							|  |  |  |    @{ | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | #include "Yap.h"
 | 
					
						
							|  |  |  | #include "Yatom.h"
 | 
					
						
							| 
									
										
										
										
											2009-10-23 14:22:17 +01:00
										 |  |  | #include "YapHeap.h"
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | #include "eval.h"
 | 
					
						
							|  |  |  | #include "yapio.h"
 | 
					
						
							| 
									
										
										
										
											2015-06-19 01:30:13 +01:00
										 |  |  | #include "blobs.h"
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | #include <stdio.h>
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | #include <unistd.h>
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | #if HAVE_STRING_H
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-10-05 10:30:17 +01:00
										 |  |  | #if HAVE_SYS_SYSCALL_H
 | 
					
						
							|  |  |  | #include <sys/syscall.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | #ifdef TABLING
 | 
					
						
							|  |  |  | #include "tab.macros.h"
 | 
					
						
							|  |  |  | #endif /* TABLING */
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-14 15:53:24 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-19 01:30:13 +01:00
										 |  |  | blob_type_t PL_Message_Queue = { | 
					
						
							|  |  |  |   YAP_BLOB_MAGIC_B, | 
					
						
							| 
									
										
										
										
											2014-10-14 15:53:24 +01:00
										 |  |  |   PL_BLOB_UNIQUE | PL_BLOB_NOCOPY, | 
					
						
							|  |  |  |   "message_queue", | 
					
						
							|  |  |  |   0, // release
 | 
					
						
							|  |  |  |   0, // compare
 | 
					
						
							|  |  |  |   0, // write
 | 
					
						
							|  |  |  |   0 // acquire
 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-19 01:54:57 +01:00
										 |  |  | #if DEBUG_LOCKS||DEBUG_PE_LOCKS
 | 
					
						
							| 
									
										
										
										
											2013-11-12 08:34:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-27 22:22:44 -05:00
										 |  |  | bool debug_locks = true, debug_pe_locks = true; | 
					
						
							| 
									
										
										
										
											2015-06-19 10:10:02 +01:00
										 |  |  | static Int p_debug_locks( USES_REGS1 ) { debug_pe_locks = 1; return TRUE; } | 
					
						
							| 
									
										
										
										
											2013-11-12 08:34:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-19 01:54:57 +01:00
										 |  |  | static Int p_nodebug_locks( USES_REGS1 ) { debug_locks = 0; debug_pe_locks = 0; return TRUE; } | 
					
						
							| 
									
										
										
										
											2013-11-12 08:34:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-11 16:18:16 +00:00
										 |  |  | #if THREADS
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-22 21:32:23 +00:00
										 |  |  | #include "threads.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-13 10:38:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  | int | 
					
						
							|  |  |  | Yap_ThreadID( void ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int new_worker_id = 0; | 
					
						
							|  |  |  |   pthread_t self = pthread_self(); | 
					
						
							|  |  |  |   while(new_worker_id < MAX_THREADS && | 
					
						
							|  |  |  | 	Yap_local[new_worker_id] && | 
					
						
							|  |  |  | 	(REMOTE_ThreadHandle(new_worker_id).in_use == TRUE || | 
					
						
							|  |  |  | 	 REMOTE_ThreadHandle(new_worker_id).zombie == TRUE) ) { | 
					
						
							|  |  |  |     if (pthread_equal(self , REMOTE_ThreadHandle(new_worker_id).pthread_handle) ) { | 
					
						
							|  |  |  |       return new_worker_id; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     new_worker_id++; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-04 22:08:37 +01:00
										 |  |  | int | 
					
						
							|  |  |  | Yap_NOfThreads(void) { | 
					
						
							|  |  |  |   // GLOBAL_ThreadHandlesLock is held
 | 
					
						
							|  |  |  |   return GLOBAL_NOfThreads; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | static int | 
					
						
							|  |  |  | allocate_new_tid(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   int new_worker_id = 0; | 
					
						
							| 
									
										
										
										
											2011-05-10 10:06:51 +01:00
										 |  |  |   LOCK(GLOBAL_ThreadHandlesLock); | 
					
						
							| 
									
										
										
										
											2008-04-02 15:41:50 +00:00
										 |  |  |   while(new_worker_id < MAX_THREADS && | 
					
						
							| 
									
										
										
										
											2011-05-09 19:36:51 +01:00
										 |  |  | 	Yap_local[new_worker_id] && | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  | 	(REMOTE_ThreadHandle(new_worker_id).in_use == TRUE || | 
					
						
							|  |  |  | 	 REMOTE_ThreadHandle(new_worker_id).zombie == TRUE) ) | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |     new_worker_id++; | 
					
						
							| 
									
										
										
										
											2011-03-23 15:15:09 +00:00
										 |  |  |   if (new_worker_id >= MAX_THREADS) { | 
					
						
							|  |  |  |     new_worker_id = -1; | 
					
						
							| 
									
										
										
										
											2011-05-09 19:36:51 +01:00
										 |  |  |   } else if (!Yap_local[new_worker_id]) { | 
					
						
							| 
									
										
										
										
											2011-03-11 19:49:32 +00:00
										 |  |  |     if (!Yap_InitThread(new_worker_id)) { | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  |       UNLOCK(GLOBAL_ThreadHandlesLock); | 
					
						
							| 
									
										
										
										
											2011-03-11 19:49:32 +00:00
										 |  |  |       return -1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-11-12 08:34:26 +00:00
										 |  |  |     MUTEX_LOCK(&(REMOTE_ThreadHandle(new_worker_id).tlock)); | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  |     REMOTE_ThreadHandle(new_worker_id).in_use = TRUE; | 
					
						
							| 
									
										
										
										
											2011-03-11 19:49:32 +00:00
										 |  |  |   } else if (new_worker_id < MAX_THREADS) { | 
					
						
							| 
									
										
										
										
											2014-10-19 01:54:57 +01:00
										 |  |  |     // reuse existing thread
 | 
					
						
							| 
									
										
										
										
											2013-11-12 08:34:26 +00:00
										 |  |  |     MUTEX_LOCK(&(REMOTE_ThreadHandle(new_worker_id).tlock)); | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  |     REMOTE_ThreadHandle(new_worker_id).in_use = TRUE; | 
					
						
							| 
									
										
										
										
											2008-03-24 23:48:47 +00:00
										 |  |  |   } else { | 
					
						
							|  |  |  |     new_worker_id = -1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-05-10 10:06:51 +01:00
										 |  |  |   UNLOCK(GLOBAL_ThreadHandlesLock); | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   return new_worker_id;   | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-14 15:53:24 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  | static bool | 
					
						
							|  |  |  | mboxCreate( Term namet, mbox_t *mboxp USES_REGS ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   pthread_mutex_t *mutexp; | 
					
						
							|  |  |  |   pthread_cond_t *condp; | 
					
						
							|  |  |  |   struct idb_queue *msgsp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   memset(mboxp, 0, sizeof(mbox_t)); | 
					
						
							|  |  |  |   condp = & mboxp->cond; | 
					
						
							|  |  |  |   pthread_cond_init(condp, NULL); | 
					
						
							|  |  |  |   mutexp = & mboxp->mutex; | 
					
						
							|  |  |  |   pthread_mutex_init(mutexp, NULL); | 
					
						
							|  |  |  |   msgsp = & mboxp->msgs; | 
					
						
							|  |  |  |   mboxp->nmsgs = 0; | 
					
						
							|  |  |  |   mboxp->nclients = 0; | 
					
						
							|  |  |  |   Yap_init_tqueue(msgsp); | 
					
						
							|  |  |  |   // match at the end, when everything is built.
 | 
					
						
							|  |  |  |   mboxp->name = namet; | 
					
						
							| 
									
										
										
										
											2014-10-19 01:54:57 +01:00
										 |  |  |   mboxp->open = true; | 
					
						
							|  |  |  |   return true; | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static bool | 
					
						
							|  |  |  | mboxDestroy( mbox_t *mboxp USES_REGS ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   pthread_mutex_t *mutexp = &mboxp->mutex; | 
					
						
							|  |  |  |   pthread_cond_t *condp = &mboxp->cond; | 
					
						
							|  |  |  |   struct idb_queue *msgsp = &mboxp->msgs; | 
					
						
							| 
									
										
										
										
											2014-10-19 01:54:57 +01:00
										 |  |  |   mboxp->open = false; | 
					
						
							|  |  |  |   if (mboxp->nclients == 0 ) { | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |     pthread_cond_destroy(condp); | 
					
						
							|  |  |  |     pthread_mutex_destroy(mutexp); | 
					
						
							|  |  |  |     Yap_destroy_tqueue(msgsp PASS_REGS); | 
					
						
							|  |  |  |     // at this point, there is nothing left to unlock!
 | 
					
						
							|  |  |  |     return true; | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |     /* we have clients in the mailbox, try to wake them up one by one */ | 
					
						
							|  |  |  |     pthread_cond_broadcast(condp); | 
					
						
							|  |  |  |     pthread_mutex_unlock(mutexp); | 
					
						
							|  |  |  |     return true; | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static bool | 
					
						
							|  |  |  | mboxSend( mbox_t *mboxp, Term t USES_REGS ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   pthread_mutex_t *mutexp = &mboxp->mutex; | 
					
						
							|  |  |  |   pthread_cond_t *condp = &mboxp->cond; | 
					
						
							|  |  |  |   struct idb_queue *msgsp = &mboxp->msgs; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-19 01:54:57 +01:00
										 |  |  |   if (!mboxp->open) { | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |     // oops, dead mailbox
 | 
					
						
							|  |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   } | 
					
						
							|  |  |  |   Yap_enqueue_tqueue(msgsp, t PASS_REGS); | 
					
						
							| 
									
										
										
										
											2014-10-19 01:54:57 +01:00
										 |  |  |   // printf("+   (%d) %d/%d\n", worker_id,mboxp->nclients, mboxp->nmsgs);
 | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   mboxp->nmsgs++; | 
					
						
							|  |  |  |   pthread_cond_broadcast(condp); | 
					
						
							|  |  |  |   pthread_mutex_unlock(mutexp); | 
					
						
							|  |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static bool | 
					
						
							|  |  |  | mboxReceive( mbox_t *mboxp, Term t USES_REGS ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   pthread_mutex_t *mutexp = &mboxp->mutex; | 
					
						
							|  |  |  |   pthread_cond_t *condp = &mboxp->cond; | 
					
						
							|  |  |  |   struct idb_queue *msgsp = &mboxp->msgs; | 
					
						
							| 
									
										
										
										
											2014-10-19 01:54:57 +01:00
										 |  |  |   bool rc;  | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-19 01:54:57 +01:00
										 |  |  |   if (!mboxp->open){ | 
					
						
							|  |  |  |     return false; 	// don't try to read if someone else already closed down...
 | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-10-19 01:54:57 +01:00
										 |  |  |   mboxp->nclients++; | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   do { | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |     rc = mboxp->nmsgs && Yap_dequeue_tqueue(msgsp, t, false,  true PASS_REGS); | 
					
						
							|  |  |  |     if (rc) { | 
					
						
							|  |  |  |       mboxp->nclients--; | 
					
						
							|  |  |  |       mboxp->nmsgs--; | 
					
						
							|  |  |  |       //printf("-   (%d) %d/%d\n", worker_id,mboxp->nclients, mboxp->nmsgs);
 | 
					
						
							|  |  |  |       //	Yap_do_low_level_trace=1;
 | 
					
						
							|  |  |  |       pthread_mutex_unlock(mutexp); | 
					
						
							|  |  |  |       return true; | 
					
						
							|  |  |  |     } else if (!mboxp->open) { | 
					
						
							|  |  |  |       //printf("o   (%d)\n", worker_id);
 | 
					
						
							|  |  |  |       mboxp->nclients--; | 
					
						
							|  |  |  |       if (!mboxp->nclients) {// release
 | 
					
						
							|  |  |  | 	pthread_cond_destroy(condp); | 
					
						
							|  |  |  | 	pthread_mutex_destroy(mutexp); | 
					
						
							|  |  |  | 	Yap_destroy_tqueue(msgsp PASS_REGS); | 
					
						
							|  |  |  | 	// at this point, there is nothing left to unlock!
 | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  | 	pthread_cond_broadcast(condp); | 
					
						
							|  |  |  | 	pthread_mutex_unlock(mutexp); | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |       return false; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       pthread_cond_wait(condp, mutexp); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   } while (!rc); | 
					
						
							|  |  |  |   return rc; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static bool | 
					
						
							|  |  |  | mboxPeek( mbox_t *mboxp, Term t USES_REGS ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   pthread_mutex_t *mutexp = &mboxp->mutex; | 
					
						
							|  |  |  |   struct idb_queue *msgsp = &mboxp->msgs; | 
					
						
							|  |  |  |   bool rc = Yap_dequeue_tqueue(msgsp, t, false,  false PASS_REGS); | 
					
						
							|  |  |  |   pthread_mutex_unlock(mutexp); | 
					
						
							|  |  |  |   return rc; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-02 17:37:07 +00:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  | store_specs(int new_worker_id, UInt ssize, UInt tsize, UInt sysize, Term tgoal, Term tdetach, Term texit) | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |     UInt pm;	/* memory to be requested         */ | 
					
						
							| 
									
										
										
										
											2008-08-07 20:51:23 +00:00
										 |  |  |   Term tmod; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-02 17:37:07 +00:00
										 |  |  |   if (tsize < MinTrailSpace) | 
					
						
							|  |  |  |     tsize = MinTrailSpace; | 
					
						
							|  |  |  |   if (ssize < MinStackSpace) | 
					
						
							|  |  |  |     ssize = MinStackSpace; | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  |   REMOTE_ThreadHandle(new_worker_id).ssize = ssize; | 
					
						
							|  |  |  |   REMOTE_ThreadHandle(new_worker_id).tsize = tsize; | 
					
						
							|  |  |  |   REMOTE_ThreadHandle(new_worker_id).sysize = sysize; | 
					
						
							| 
									
										
										
										
											2013-09-17 00:26:37 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if ((REGSTORE *)pthread_getspecific(Yap_yaamregs_key)) { | 
					
						
							|  |  |  |     REMOTE_c_input_stream(new_worker_id) = LOCAL_c_input_stream; | 
					
						
							|  |  |  |     REMOTE_c_output_stream(new_worker_id) = LOCAL_c_output_stream; | 
					
						
							|  |  |  |     REMOTE_c_error_stream(new_worker_id) = LOCAL_c_error_stream; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     // thread is created by a thread that has never run Prolog
 | 
					
						
							|  |  |  |     REMOTE_c_input_stream(new_worker_id) = REMOTE_c_input_stream(0); | 
					
						
							|  |  |  |     REMOTE_c_output_stream(new_worker_id) = REMOTE_c_output_stream(0); | 
					
						
							|  |  |  |     REMOTE_c_error_stream(new_worker_id) = REMOTE_c_error_stream(0); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-12-17 15:57:24 +00:00
										 |  |  |   pm = (ssize + tsize)*K1; | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  |   if (!(REMOTE_ThreadHandle(new_worker_id).stack_address = malloc(pm))) { | 
					
						
							| 
									
										
										
										
											2008-04-02 17:37:07 +00:00
										 |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  |   REMOTE_ThreadHandle(new_worker_id).tgoal = | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |     Yap_StoreTermInDB(Deref(tgoal), 7); | 
					
						
							| 
									
										
										
										
											2013-09-28 23:20:39 +01:00
										 |  |  |        | 
					
						
							|  |  |  |   if (CurrentModule) { | 
					
						
							|  |  |  |     REMOTE_ThreadHandle(new_worker_id).cmod = | 
					
						
							|  |  |  |       CurrentModule; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     REMOTE_ThreadHandle(new_worker_id).cmod = USER_MODULE; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   tdetach = Deref(tdetach); | 
					
						
							| 
									
										
										
										
											2004-02-19 19:24:46 +00:00
										 |  |  |   if (IsVarTerm(tdetach)){ | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  |     REMOTE_ThreadHandle(new_worker_id).tdetach =   | 
					
						
							| 
									
										
										
										
											2004-02-19 19:24:46 +00:00
										 |  |  |       MkAtomTerm(AtomFalse); | 
					
						
							|  |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  |     REMOTE_ThreadHandle(new_worker_id).tdetach =  | 
					
						
							| 
									
										
										
										
											2004-02-19 19:24:46 +00:00
										 |  |  |       tdetach; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-10-14 02:10:18 +01:00
										 |  |  |   tmod = CurrentModule; | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   texit = Yap_StripModule(Deref(texit), &tmod); | 
					
						
							| 
									
										
										
										
											2014-10-14 02:10:18 +01:00
										 |  |  |   if (IsAtomTerm(tmod)) { | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |     REMOTE_ThreadHandle(new_worker_id).texit_mod = tmod; | 
					
						
							| 
									
										
										
										
											2014-10-14 02:10:18 +01:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |     Yap_Error(TYPE_ERROR_ATOM,tmod,"module in exit call should be an atom"); | 
					
						
							| 
									
										
										
										
											2014-10-14 02:10:18 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  |   REMOTE_ThreadHandle(new_worker_id).texit = | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |     Yap_StoreTermInDB(texit,7); | 
					
						
							| 
									
										
										
										
											2011-11-30 13:03:22 +00:00
										 |  |  |   REMOTE_ThreadHandle(new_worker_id).local_preds = | 
					
						
							|  |  |  |     NULL; | 
					
						
							| 
									
										
										
										
											2011-12-01 11:05:27 +00:00
										 |  |  |   REMOTE_ThreadHandle(new_worker_id).start_of_timesp = | 
					
						
							|  |  |  |     NULL; | 
					
						
							|  |  |  |   REMOTE_ThreadHandle(new_worker_id).last_timep = | 
					
						
							|  |  |  |     NULL; | 
					
						
							|  |  |  |   REMOTE_ScratchPad(new_worker_id).ptr = | 
					
						
							|  |  |  |     NULL; | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   // reset arena info
 | 
					
						
							|  |  |  |   REMOTE_GlobalArena(new_worker_id) =0; | 
					
						
							| 
									
										
										
										
											2008-04-02 17:37:07 +00:00
										 |  |  |   return TRUE; | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-22 21:32:23 +00:00
										 |  |  | static void | 
					
						
							| 
									
										
										
										
											2008-08-06 17:32:22 +00:00
										 |  |  | kill_thread_engine (int wid, int always_die) | 
					
						
							| 
									
										
										
										
											2004-07-22 21:32:23 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  |   Prop p0 = AbsPredProp(REMOTE_ThreadHandle(wid).local_preds); | 
					
						
							| 
									
										
										
										
											2011-12-01 11:05:27 +00:00
										 |  |  |   GlobalEntry *gl = REMOTE_GlobalVariables(wid); | 
					
						
							| 
									
										
										
										
											2004-12-02 06:06:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  |   REMOTE_ThreadHandle(wid).local_preds = NIL; | 
					
						
							| 
									
										
										
										
											2011-12-01 11:05:27 +00:00
										 |  |  |   REMOTE_GlobalVariables(wid) = NULL; | 
					
						
							| 
									
										
										
										
											2004-07-22 21:32:23 +00:00
										 |  |  |   /* kill all thread local preds */ | 
					
						
							|  |  |  |   while(p0) { | 
					
						
							|  |  |  |     PredEntry *ap = RepPredProp(p0); | 
					
						
							|  |  |  |     p0 = ap->NextOfPE; | 
					
						
							|  |  |  |     Yap_Abolish(ap); | 
					
						
							|  |  |  |     Yap_FreeCodeSpace((char *)ap); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2009-05-17 10:38:39 -07:00
										 |  |  |   while (gl) { | 
					
						
							|  |  |  |     gl->global = TermFoundVar; | 
					
						
							|  |  |  |     gl = gl->NextGE; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-07-22 21:32:23 +00:00
										 |  |  |   Yap_KillStacks(wid); | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  |   REMOTE_Signals(wid) = 0L; | 
					
						
							| 
									
										
										
										
											2014-10-15 12:32:00 +01:00
										 |  |  |   // must be done before relessing the memory used to store 
 | 
					
						
							|  |  |  |   // thread local time.
 | 
					
						
							|  |  |  |   if (!always_die) { | 
					
						
							|  |  |  |     /* called by thread itself */ | 
					
						
							|  |  |  |     GLOBAL_ThreadsTotalTime += Yap_cputime(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-12-01 11:05:27 +00:00
										 |  |  |   if (REMOTE_ScratchPad(wid).ptr) | 
					
						
							|  |  |  |     free(REMOTE_ScratchPad(wid).ptr); | 
					
						
							| 
									
										
										
										
											2014-11-25 12:03:48 +00:00
										 |  |  | //  if (REMOTE_TmpPred(wid).ptr)
 | 
					
						
							|  |  |  | //    free(REMOTE_TmpPred(wid).ptr);
 | 
					
						
							| 
									
										
										
										
											2013-11-15 01:10:25 +00:00
										 |  |  |     REMOTE_ThreadHandle(wid).current_yaam_regs = NULL; | 
					
						
							| 
									
										
										
										
											2011-12-01 11:05:27 +00:00
										 |  |  |   if (REMOTE_ThreadHandle(wid).start_of_timesp) | 
					
						
							|  |  |  |     free(REMOTE_ThreadHandle(wid).start_of_timesp); | 
					
						
							|  |  |  |   if (REMOTE_ThreadHandle(wid).last_timep) | 
					
						
							|  |  |  |     free(REMOTE_ThreadHandle(wid).last_timep); | 
					
						
							|  |  |  |   if (REMOTE_ThreadHandle(wid).texit) { | 
					
						
							|  |  |  |     Yap_FreeCodeSpace((ADDR)REMOTE_ThreadHandle(wid).texit); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* FreeCodeSpace requires LOCAL requires yaam_regs */ | 
					
						
							|  |  |  |   free(REMOTE_ThreadHandle(wid).default_yaam_regs); | 
					
						
							|  |  |  |   REMOTE_ThreadHandle(wid).default_yaam_regs = NULL; | 
					
						
							| 
									
										
										
										
											2011-05-10 10:06:51 +01:00
										 |  |  |   LOCK(GLOBAL_ThreadHandlesLock); | 
					
						
							| 
									
										
										
										
											2012-05-14 19:11:58 +01:00
										 |  |  |   GLOBAL_NOfThreads--; | 
					
						
							| 
									
										
										
										
											2014-10-19 01:54:57 +01:00
										 |  |  |   UNLOCK(GLOBAL_ThreadHandlesLock); | 
					
						
							| 
									
										
										
										
											2013-11-12 08:43:45 +00:00
										 |  |  |   MUTEX_LOCK(&(REMOTE_ThreadHandle(wid).tlock)); | 
					
						
							|  |  |  |   if (REMOTE_ThreadHandle(wid).tdetach == MkAtomTerm(AtomTrue) || | 
					
						
							|  |  |  |       always_die) { | 
					
						
							|  |  |  |     REMOTE_ThreadHandle(wid).zombie = FALSE; | 
					
						
							|  |  |  |     REMOTE_ThreadHandle(wid).in_use = FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   MUTEX_UNLOCK(&(REMOTE_ThreadHandle(wid).tlock)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | thread_die(int wid, int always_die) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2008-08-06 17:32:22 +00:00
										 |  |  |   kill_thread_engine(wid, always_die); | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-01 11:05:27 +00:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											2010-07-30 12:08:00 +01:00
										 |  |  | setup_engine(int myworker_id, int init_thread) | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |     REGSTORE *standard_regs; | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |    | 
					
						
							| 
									
										
										
										
											2008-05-10 23:24:13 +00:00
										 |  |  |   standard_regs = (REGSTORE *)calloc(1,sizeof(REGSTORE)); | 
					
						
							| 
									
										
										
										
											2011-12-01 11:05:27 +00:00
										 |  |  |   if (!standard_regs) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2011-03-10 11:05:39 +00:00
										 |  |  |   regcache = standard_regs; | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   /* create the YAAM descriptor */ | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  |   REMOTE_ThreadHandle(myworker_id).default_yaam_regs = standard_regs; | 
					
						
							| 
									
										
										
										
											2013-11-15 01:10:25 +00:00
										 |  |  |   REMOTE_ThreadHandle(myworker_id).current_yaam_regs = standard_regs; | 
					
						
							| 
									
										
										
										
											2012-12-13 18:12:50 +00:00
										 |  |  |   Yap_InitExStacks(myworker_id, REMOTE_ThreadHandle(myworker_id).tsize, REMOTE_ThreadHandle(myworker_id).ssize); | 
					
						
							| 
									
										
										
										
											2013-11-20 22:24:31 +00:00
										 |  |  |   REMOTE_SourceModule(myworker_id) = CurrentModule = REMOTE_ThreadHandle(myworker_id).cmod; | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   // create a mbox
 | 
					
						
							|  |  |  |   mboxCreate( MkIntTerm(myworker_id), &REMOTE_ThreadHandle(myworker_id).mbox_handle PASS_REGS ); | 
					
						
							| 
									
										
										
										
											2012-12-11 22:07:10 +00:00
										 |  |  |   Yap_InitTime( myworker_id ); | 
					
						
							|  |  |  |   Yap_InitYaamRegs( myworker_id ); | 
					
						
							| 
									
										
										
										
											2012-12-13 18:12:50 +00:00
										 |  |  |   REFRESH_CACHE_REGS | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |     Yap_ReleasePreAllocCodeSpace(Yap_PreAllocCodeSpace()); | 
					
						
							| 
									
										
										
										
											2004-07-22 21:32:23 +00:00
										 |  |  |   /* I exist */ | 
					
						
							| 
									
										
										
										
											2011-05-10 10:06:51 +01:00
										 |  |  |   GLOBAL_NOfThreadsCreated++; | 
					
						
							| 
									
										
										
										
											2012-05-14 19:11:58 +01:00
										 |  |  |   GLOBAL_NOfThreads++; | 
					
						
							| 
									
										
										
										
											2013-11-12 08:34:26 +00:00
										 |  |  |   MUTEX_UNLOCK(&(REMOTE_ThreadHandle(myworker_id).tlock));   | 
					
						
							| 
									
										
										
										
											2011-07-26 16:49:49 +01:00
										 |  |  | #ifdef TABLING
 | 
					
						
							| 
									
										
										
										
											2012-12-11 22:07:10 +00:00
										 |  |  |   new_dependency_frame(REMOTE_top_dep_fr(myworker_id), FALSE, NULL, NULL, B, NULL, FALSE, NULL);  /* same as in Yap_init_root_frames() */ | 
					
						
							| 
									
										
										
										
											2011-07-26 16:49:49 +01:00
										 |  |  | #endif /* TABLING */
 | 
					
						
							| 
									
										
										
										
											2011-12-01 11:05:27 +00:00
										 |  |  |   return TRUE; | 
					
						
							| 
									
										
										
										
											2004-07-22 21:32:23 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | start_thread(int myworker_id) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-12-13 18:12:50 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |     pthread_setspecific(Yap_yaamregs_key, (void *)REMOTE_ThreadHandle(myworker_id).default_yaam_regs); | 
					
						
							| 
									
										
										
										
											2012-12-13 18:12:50 +00:00
										 |  |  |   REFRESH_CACHE_REGS; | 
					
						
							|  |  |  |   worker_id = myworker_id; | 
					
						
							|  |  |  |   LOCAL = REMOTE(myworker_id); | 
					
						
							| 
									
										
										
										
											2004-07-22 21:32:23 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void * | 
					
						
							|  |  |  | thread_run(void *widp) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |     Term tgoal, t; | 
					
						
							| 
									
										
										
										
											2004-07-22 21:32:23 +00:00
										 |  |  |   Term tgs[2]; | 
					
						
							|  |  |  |   int myworker_id = *((int *)widp);  | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | #ifdef OUTPUT_THREADS_TABLING
 | 
					
						
							|  |  |  |   char thread_name[25]; | 
					
						
							|  |  |  |   char filename[YAP_FILENAME_MAX];  | 
					
						
							| 
									
										
										
										
											2012-12-13 18:12:50 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  |   sprintf(thread_name, "/thread_output_%d", myworker_id); | 
					
						
							|  |  |  |   strcpy(filename, YAP_BINDIR); | 
					
						
							|  |  |  |   strncat(filename, thread_name, 25); | 
					
						
							| 
									
										
										
										
											2012-12-13 18:12:50 +00:00
										 |  |  |   REMOTE_thread_output(myworker_id) = fopen(filename, "w"); | 
					
						
							| 
									
										
										
										
											2011-12-22 16:50:20 +00:00
										 |  |  | #endif /* OUTPUT_THREADS_TABLING */
 | 
					
						
							| 
									
										
										
										
											2004-07-22 21:32:23 +00:00
										 |  |  |   start_thread(myworker_id); | 
					
						
							| 
									
										
										
										
											2012-12-13 18:12:50 +00:00
										 |  |  |   REFRESH_CACHE_REGS; | 
					
						
							| 
									
										
										
										
											2008-01-27 11:01:07 +00:00
										 |  |  |   do { | 
					
						
							| 
									
										
										
										
											2011-05-09 19:55:06 +01:00
										 |  |  |     t = tgs[0] = Yap_PopTermFromDB(LOCAL_ThreadHandle.tgoal); | 
					
						
							| 
									
										
										
										
											2008-01-27 11:01:07 +00:00
										 |  |  |     if (t == 0) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       if (LOCAL_Error_TYPE == RESOURCE_ERROR_ATTRIBUTED_VARIABLES) { | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  | 	LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							| 
									
										
										
										
											2008-01-27 11:01:07 +00:00
										 |  |  | 	if (!Yap_growglobal(NULL)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 	  Yap_Error(RESOURCE_ERROR_ATTRIBUTED_VARIABLES, TermNil, LOCAL_ErrorMessage); | 
					
						
							| 
									
										
										
										
											2008-01-27 11:01:07 +00:00
										 |  |  | 	  thread_die(worker_id, FALSE); | 
					
						
							|  |  |  | 	  return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2011-05-23 16:19:47 +01:00
										 |  |  | 	LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							| 
									
										
										
										
											2011-05-09 19:55:06 +01:00
										 |  |  | 	if (!Yap_growstack(LOCAL_ThreadHandle.tgoal->NOfCells*CellSize)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 	  Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage); | 
					
						
							| 
									
										
										
										
											2008-01-27 11:01:07 +00:00
										 |  |  | 	  thread_die(worker_id, FALSE); | 
					
						
							|  |  |  | 	  return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } while (t == 0); | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  |   REMOTE_ThreadHandle(myworker_id).tgoal = NULL; | 
					
						
							| 
									
										
										
										
											2011-05-09 19:55:06 +01:00
										 |  |  |   tgs[1] = LOCAL_ThreadHandle.tdetach; | 
					
						
							| 
									
										
										
										
											2004-02-11 01:20:56 +00:00
										 |  |  |   tgoal = Yap_MkApplTerm(FunctorThreadRun, 2, tgs); | 
					
						
							| 
									
										
										
										
											2006-05-25 16:57:21 +00:00
										 |  |  |   Yap_RunTopGoal(tgoal); | 
					
						
							| 
									
										
										
										
											2013-12-15 10:27:53 +00:00
										 |  |  | #ifdef TABLING
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     tab_ent_ptr tab_ent; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     tab_ent = GLOBAL_root_tab_ent; | 
					
						
							|  |  |  |     while (tab_ent) { | 
					
						
							|  |  |  |       abolish_table(tab_ent); | 
					
						
							|  |  |  |       tab_ent = TabEnt_next(tab_ent); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     FREE_DEPENDENCY_FRAME(REMOTE_top_dep_fr(worker_id)); | 
					
						
							|  |  |  |     REMOTE_top_dep_fr(worker_id) = NULL; | 
					
						
							|  |  |  | #ifdef USE_PAGES_MALLOC
 | 
					
						
							|  |  |  |     DETACH_PAGES(_pages_void); | 
					
						
							|  |  |  | #endif /* USE_PAGES_MALLOC */
 | 
					
						
							|  |  |  |     DETACH_PAGES(_pages_tab_ent); | 
					
						
							|  |  |  | #if defined(THREADS_FULL_SHARING) || defined(THREADS_CONSUMER_SHARING)
 | 
					
						
							|  |  |  |     DETACH_PAGES(_pages_sg_ent); | 
					
						
							|  |  |  | #endif /* THREADS_FULL_SHARING || THREADS_CONSUMER_SHARING */
 | 
					
						
							|  |  |  |     DETACH_PAGES(_pages_sg_fr); | 
					
						
							|  |  |  |     DETACH_PAGES(_pages_dep_fr); | 
					
						
							|  |  |  |     DETACH_PAGES(_pages_sg_node); | 
					
						
							|  |  |  |     DETACH_PAGES(_pages_sg_hash); | 
					
						
							|  |  |  |     DETACH_PAGES(_pages_ans_node); | 
					
						
							|  |  |  |     DETACH_PAGES(_pages_ans_hash); | 
					
						
							|  |  |  | #if defined(THREADS_FULL_SHARING)
 | 
					
						
							|  |  |  |     DETACH_PAGES(_pages_ans_ref_node); | 
					
						
							|  |  |  | #endif /* THREADS_FULL_SHARING */
 | 
					
						
							|  |  |  |     DETACH_PAGES(_pages_gt_node); | 
					
						
							|  |  |  |     DETACH_PAGES(_pages_gt_hash); | 
					
						
							|  |  |  | #ifdef OUTPUT_THREADS_TABLING 
 | 
					
						
							|  |  |  |     fclose(LOCAL_thread_output); | 
					
						
							|  |  |  | #endif /* OUTPUT_THREADS_TABLING */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif /* TABLING */
 | 
					
						
							| 
									
										
										
										
											2004-02-21 20:25:45 +00:00
										 |  |  |   thread_die(worker_id, FALSE); | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-11 01:20:56 +00:00
										 |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_thread_new_tid( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2004-02-11 01:20:56 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-03-24 23:48:47 +00:00
										 |  |  |   int new_worker = allocate_new_tid(); | 
					
						
							|  |  |  |   if (new_worker == -1) { | 
					
						
							| 
									
										
										
										
											2008-04-02 15:41:50 +00:00
										 |  |  |     Yap_Error(RESOURCE_ERROR_MAX_THREADS, MkIntegerTerm(MAX_THREADS), ""); | 
					
						
							| 
									
										
										
										
											2008-03-24 23:48:47 +00:00
										 |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return Yap_unify(MkIntegerTerm(new_worker), ARG1); | 
					
						
							| 
									
										
										
										
											2004-02-11 01:20:56 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-02 17:37:07 +00:00
										 |  |  | static int | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  | init_thread_engine(int new_worker_id, UInt ssize, UInt tsize, UInt sysize, Term tgoal, Term tdetach, Term texit) | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-08-07 20:51:23 +00:00
										 |  |  |   return store_specs(new_worker_id, ssize, tsize, sysize, tgoal, tdetach, texit); | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-15 15:47:08 +00:00
										 |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_create_thread( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2004-07-15 15:47:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-04-02 17:37:07 +00:00
										 |  |  |   UInt ssize; | 
					
						
							|  |  |  |   UInt tsize; | 
					
						
							| 
									
										
										
										
											2008-08-07 20:51:23 +00:00
										 |  |  |   UInt sysize; | 
					
						
							| 
									
										
										
										
											2008-04-02 17:37:07 +00:00
										 |  |  |   Term x2 = Deref(ARG2); | 
					
						
							|  |  |  |   Term x3 = Deref(ARG3); | 
					
						
							| 
									
										
										
										
											2008-08-07 20:51:23 +00:00
										 |  |  |   Term x4 = Deref(ARG4); | 
					
						
							| 
									
										
										
										
											2012-12-13 18:12:50 +00:00
										 |  |  |   int new_worker_id = IntegerOfTerm(Deref(ARG7)), | 
					
						
							|  |  |  |     owid = worker_id; | 
					
						
							| 
									
										
										
										
											2004-07-15 15:47:08 +00:00
										 |  |  |    | 
					
						
							| 
									
										
										
										
											2008-08-06 17:32:22 +00:00
										 |  |  |   //  fprintf(stderr," %d --> %d\n", worker_id, new_worker_id); 
 | 
					
						
							| 
									
										
										
										
											2008-04-02 17:37:07 +00:00
										 |  |  |   if (IsBigIntTerm(x2)) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   if (IsBigIntTerm(x3)) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   ssize = IntegerOfTerm(x2); | 
					
						
							|  |  |  |   tsize = IntegerOfTerm(x3); | 
					
						
							| 
									
										
										
										
											2008-08-07 20:51:23 +00:00
										 |  |  |   sysize = IntegerOfTerm(x4); | 
					
						
							| 
									
										
										
										
											2008-04-02 17:37:07 +00:00
										 |  |  |   /*  UInt systemsize = IntegerOfTerm(Deref(ARG4)); */ | 
					
						
							| 
									
										
										
										
											2004-07-15 15:47:08 +00:00
										 |  |  |   if (new_worker_id == -1) { | 
					
						
							|  |  |  |     /* YAP ERROR */ | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-08-06 17:32:22 +00:00
										 |  |  |   /* make sure we can proceed */ | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   if (!init_thread_engine(new_worker_id, ssize, tsize, sysize, ARG1, ARG5, ARG6)) | 
					
						
							| 
									
										
										
										
											2008-04-02 17:37:07 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2012-06-29 15:37:31 -05:00
										 |  |  |   //REMOTE_ThreadHandle(new_worker_id).pthread_handle = 0L;
 | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  |   REMOTE_ThreadHandle(new_worker_id).id = new_worker_id; | 
					
						
							|  |  |  |   REMOTE_ThreadHandle(new_worker_id).ref_count = 1; | 
					
						
							| 
									
										
										
										
											2012-12-13 18:12:50 +00:00
										 |  |  |   setup_engine(new_worker_id, FALSE); | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  |   if ((REMOTE_ThreadHandle(new_worker_id).ret = pthread_create(&REMOTE_ThreadHandle(new_worker_id).pthread_handle, NULL, thread_run, (void *)(&(REMOTE_ThreadHandle(new_worker_id).id)))) == 0) { | 
					
						
							| 
									
										
										
										
											2012-12-13 18:12:50 +00:00
										 |  |  |     pthread_setspecific(Yap_yaamregs_key, (const void *)REMOTE_ThreadHandle(owid).current_yaam_regs); | 
					
						
							| 
									
										
										
										
											2015-11-05 16:35:25 +00:00
										 |  |  |     /* wait until the client is initialized */ | 
					
						
							| 
									
										
										
										
											2004-07-15 15:47:08 +00:00
										 |  |  |     return TRUE; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-12-13 18:12:50 +00:00
										 |  |  |   pthread_setspecific(Yap_yaamregs_key, (const void *)REMOTE_ThreadHandle(owid).current_yaam_regs); | 
					
						
							| 
									
										
										
										
											2004-07-15 15:47:08 +00:00
										 |  |  |   return FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-05-25 16:28:28 +00:00
										 |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_thread_sleep( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2006-05-25 16:28:28 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   UInt time = IntegerOfTerm(Deref(ARG1)); | 
					
						
							|  |  |  | #if HAVE_NANOSLEEP
 | 
					
						
							|  |  |  |   UInt ntime = IntegerOfTerm(Deref(ARG2)); | 
					
						
							|  |  |  |   struct timespec req, oreq ; | 
					
						
							|  |  |  |   req.tv_sec = time; | 
					
						
							|  |  |  |   req.tv_nsec = ntime; | 
					
						
							| 
									
										
										
										
											2006-12-31 16:10:29 +00:00
										 |  |  |   if (nanosleep(&req, &oreq)) { | 
					
						
							| 
									
										
										
										
											2006-05-25 16:28:28 +00:00
										 |  |  | #if HAVE_STRERROR
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Yap_Error(SYSTEM_ERROR_OPERATING_SYSTEM, ARG1, "%s in thread_sleep/1", strerror(errno)); | 
					
						
							| 
									
										
										
										
											2006-05-25 16:28:28 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Yap_Error(SYSTEM_ERROR_OPERATING_SYSTEM, ARG1, "error %d in thread_sleep/1", errno); | 
					
						
							| 
									
										
										
										
											2006-05-25 16:28:28 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return Yap_unify(ARG3,MkIntegerTerm(oreq.tv_sec)) && | 
					
						
							|  |  |  |     Yap_unify(ARG4,MkIntegerTerm(oreq.tv_nsec)); | 
					
						
							|  |  |  | #elif HAVE_SLEEP
 | 
					
						
							|  |  |  |   UInt rtime; | 
					
						
							|  |  |  |   if ((rtime = sleep(time)) < 0) { | 
					
						
							|  |  |  | #if HAVE_STRERROR
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Yap_Error(SYSTEM_ERROR_OPERATING_SYSTEM, ARG1, "%s in thread_sleep/1", strerror(errno)); | 
					
						
							| 
									
										
										
										
											2006-05-25 16:28:28 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |     Yap_Error(SYSTEM_ERROR_OPERATING_SYSTEM, ARG1, "error %d in thread_sleep/1", errno); | 
					
						
							| 
									
										
										
										
											2006-05-25 16:28:28 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return Yap_unify(ARG3,MkIntegerTerm(rtime)) && | 
					
						
							|  |  |  |     Yap_unify(ARG4,MkIntTerm(0L)); | 
					
						
							|  |  |  | #else 
 | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |   Yap_Error(SYSTEM_ERROR_OPERATING_SYSTEM, ARG1, "no support for thread_sleep/1 in this YAP configuration"); | 
					
						
							| 
									
										
										
										
											2006-05-25 16:28:28 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_thread_self( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2004-08-11 16:14:55 +00:00
										 |  |  |   if (pthread_getspecific(Yap_yaamregs_key) == NULL) | 
					
						
							|  |  |  |     return Yap_unify(MkIntegerTerm(-1), ARG1); | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   return Yap_unify(MkIntegerTerm(worker_id), ARG1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-27 11:01:07 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_thread_zombie_self( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2008-01-27 11:01:07 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   /* make sure the lock is available */ | 
					
						
							|  |  |  |   if (pthread_getspecific(Yap_yaamregs_key) == NULL) | 
					
						
							|  |  |  |     return Yap_unify(MkIntegerTerm(-1), ARG1); | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  |   if (Yap_has_signal( YAP_ITI_SIGNAL )) { | 
					
						
							| 
									
										
										
										
											2008-01-27 11:01:07 +00:00
										 |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2008-08-06 17:32:22 +00:00
										 |  |  |   //  fprintf(stderr," -- %d\n", worker_id); 
 | 
					
						
							| 
									
										
										
										
											2011-05-09 19:55:06 +01:00
										 |  |  |   LOCAL_ThreadHandle.in_use = FALSE; | 
					
						
							|  |  |  |   LOCAL_ThreadHandle.zombie = TRUE; | 
					
						
							| 
									
										
										
										
											2013-11-12 08:43:45 +00:00
										 |  |  |   MUTEX_UNLOCK(&(LOCAL_ThreadHandle.tlock)); | 
					
						
							| 
									
										
										
										
											2008-08-06 17:32:22 +00:00
										 |  |  |   return Yap_unify(MkIntegerTerm(worker_id), ARG1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_thread_status_lock( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2008-08-06 17:32:22 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   /* make sure the lock is available */ | 
					
						
							|  |  |  |   if (pthread_getspecific(Yap_yaamregs_key) == NULL) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2013-11-12 08:34:26 +00:00
										 |  |  |   MUTEX_LOCK(&(LOCAL_ThreadHandle.tlock_status)); | 
					
						
							| 
									
										
										
										
											2008-08-06 17:32:22 +00:00
										 |  |  |   return Yap_unify(MkIntegerTerm(worker_id), ARG1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_thread_status_unlock( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2008-08-06 17:32:22 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   /* make sure the lock is available */ | 
					
						
							|  |  |  |   if (pthread_getspecific(Yap_yaamregs_key) == NULL) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2013-11-12 08:34:26 +00:00
										 |  |  |   MUTEX_UNLOCK(&(LOCAL_ThreadHandle.tlock_status)); | 
					
						
							| 
									
										
										
										
											2008-01-27 11:01:07 +00:00
										 |  |  |   return Yap_unify(MkIntegerTerm(worker_id), ARG1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-03-13 06:26:13 +00:00
										 |  |  | Int | 
					
						
							| 
									
										
										
										
											2004-07-22 21:32:23 +00:00
										 |  |  | Yap_thread_self(void) | 
					
						
							| 
									
										
										
										
											2004-07-15 15:47:08 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |     if (pthread_getspecific(Yap_yaamregs_key) == NULL) | 
					
						
							|  |  |  |       return -1; | 
					
						
							| 
									
										
										
										
											2004-07-15 15:47:08 +00:00
										 |  |  |   return worker_id; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-03-13 06:26:13 +00:00
										 |  |  | CELL | 
					
						
							| 
									
										
										
										
											2014-05-25 20:50:07 +01:00
										 |  |  | Yap_thread_create_engine(YAP_thread_attr *ops) | 
					
						
							| 
									
										
										
										
											2004-07-22 21:32:23 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-05-25 20:50:07 +01:00
										 |  |  |   YAP_thread_attr opsv; | 
					
						
							| 
									
										
										
										
											2004-07-22 21:32:23 +00:00
										 |  |  |   int new_id = allocate_new_tid(); | 
					
						
							| 
									
										
										
										
											2010-07-23 12:07:33 +01:00
										 |  |  |   Term t = TermNil; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* 
 | 
					
						
							| 
									
										
										
										
											2012-12-11 22:07:10 +00:00
										 |  |  |      ok, this creates a problem, because we are initializing an engine from | 
					
						
							|  |  |  |      some "empty" thread.  | 
					
						
							|  |  |  |      We need first to fool the thread into believing it is the main thread | 
					
						
							| 
									
										
										
										
											2010-07-23 12:07:33 +01:00
										 |  |  |   */ | 
					
						
							| 
									
										
										
										
											2004-07-22 21:32:23 +00:00
										 |  |  |   if (new_id == -1) { | 
					
						
							|  |  |  |     /* YAP ERROR */ | 
					
						
							| 
									
										
										
										
											2010-07-23 15:54:13 +01:00
										 |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2004-07-22 21:32:23 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-06-14 09:27:48 +01:00
										 |  |  |   if (ops == NULL) { | 
					
						
							|  |  |  |     ops = &opsv; | 
					
						
							|  |  |  |     ops->tsize = DefHeapSpace; | 
					
						
							|  |  |  |     ops->ssize = DefStackSpace; | 
					
						
							|  |  |  |     ops->sysize = 0; | 
					
						
							|  |  |  |     ops->egoal = t; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-06-29 15:37:31 -05:00
										 |  |  |   if (!pthread_equal(pthread_self() , GLOBAL_master_thread) ) { | 
					
						
							| 
									
										
										
										
											2010-07-23 12:07:33 +01:00
										 |  |  |     /* we are worker_id 0 for now, lock master thread so that no one messes with us */  | 
					
						
							| 
									
										
										
										
											2010-07-25 11:21:15 +01:00
										 |  |  |     pthread_setspecific(Yap_yaamregs_key, (const void *)&Yap_standard_regs); | 
					
						
							| 
									
										
										
										
											2013-11-12 08:34:26 +00:00
										 |  |  |     MUTEX_LOCK(&(REMOTE_ThreadHandle(0).tlock)); | 
					
						
							| 
									
										
										
										
											2010-07-23 12:07:33 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |   if (!init_thread_engine(new_id, ops->ssize, ops->tsize, ops->sysize, t, t, (ops->egoal))) | 
					
						
							| 
									
										
										
										
											2010-07-23 15:54:13 +01:00
										 |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2012-06-29 15:37:31 -05:00
										 |  |  |   //REMOTE_ThreadHandle(new_id).pthread_handle = 0L;
 | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  |   REMOTE_ThreadHandle(new_id).id = new_id; | 
					
						
							|  |  |  |   REMOTE_ThreadHandle(new_id).ref_count = 0; | 
					
						
							| 
									
										
										
										
											2011-12-01 11:05:27 +00:00
										 |  |  |   if (!setup_engine(new_id, FALSE)) | 
					
						
							|  |  |  |     return -1; | 
					
						
							| 
									
										
										
										
											2012-06-29 15:37:31 -05:00
										 |  |  |   if (!pthread_equal(pthread_self(), GLOBAL_master_thread)) { | 
					
						
							| 
									
										
										
										
											2010-07-25 11:21:15 +01:00
										 |  |  |     pthread_setspecific(Yap_yaamregs_key, NULL); | 
					
						
							| 
									
										
										
										
											2013-11-12 08:34:26 +00:00
										 |  |  |     MUTEX_UNLOCK(&(REMOTE_ThreadHandle(0).tlock)); | 
					
						
							| 
									
										
										
										
											2010-07-23 12:07:33 +01:00
										 |  |  |   } | 
					
						
							|  |  |  |   return new_id; | 
					
						
							| 
									
										
										
										
											2004-07-22 21:32:23 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-03-13 06:26:13 +00:00
										 |  |  | Int | 
					
						
							| 
									
										
										
										
											2004-07-22 21:32:23 +00:00
										 |  |  | Yap_thread_attach_engine(int wid) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-07-25 11:21:15 +01:00
										 |  |  |   /* 
 | 
					
						
							|  |  |  |      already locked | 
					
						
							| 
									
										
										
										
											2013-11-12 08:34:26 +00:00
										 |  |  |      MUTEX_LOCK(&(REMOTE_ThreadHandle(wid).tlock)); | 
					
						
							| 
									
										
										
										
											2010-07-25 11:21:15 +01:00
										 |  |  |   */ | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  |   if (REMOTE_ThreadHandle(wid).ref_count ) { | 
					
						
							|  |  |  |     REMOTE_ThreadHandle(wid).ref_count++; | 
					
						
							|  |  |  |     REMOTE_ThreadHandle(wid).pthread_handle = pthread_self(); | 
					
						
							| 
									
										
										
										
											2013-11-12 08:34:26 +00:00
										 |  |  |     MUTEX_UNLOCK(&(REMOTE_ThreadHandle(wid).tlock)); | 
					
						
							| 
									
										
										
										
											2010-07-23 15:54:13 +01:00
										 |  |  |     return TRUE; | 
					
						
							| 
									
										
										
										
											2004-08-11 16:14:55 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  |   REMOTE_ThreadHandle(wid).pthread_handle = pthread_self(); | 
					
						
							|  |  |  |   REMOTE_ThreadHandle(wid).ref_count++; | 
					
						
							| 
									
										
										
										
											2012-12-13 18:12:50 +00:00
										 |  |  |   pthread_setspecific(Yap_yaamregs_key, (const void *)REMOTE_ThreadHandle(wid).current_yaam_regs); | 
					
						
							| 
									
										
										
										
											2013-11-12 08:34:26 +00:00
										 |  |  |   MUTEX_UNLOCK(&(REMOTE_ThreadHandle(wid).tlock)); | 
					
						
							| 
									
										
										
										
											2004-07-22 21:32:23 +00:00
										 |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-03-13 06:26:13 +00:00
										 |  |  | Int | 
					
						
							| 
									
										
										
										
											2004-07-22 21:32:23 +00:00
										 |  |  | Yap_thread_detach_engine(int wid) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-12 08:34:26 +00:00
										 |  |  |   MUTEX_LOCK(&(REMOTE_ThreadHandle(wid).tlock)); | 
					
						
							| 
									
										
										
										
											2012-06-29 15:37:31 -05:00
										 |  |  |   //REMOTE_ThreadHandle(wid).pthread_handle = 0;
 | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  |   REMOTE_ThreadHandle(wid).ref_count--; | 
					
						
							| 
									
										
										
										
											2010-07-25 11:21:15 +01:00
										 |  |  |   pthread_setspecific(Yap_yaamregs_key, NULL); | 
					
						
							| 
									
										
										
										
											2013-11-12 08:34:26 +00:00
										 |  |  |   MUTEX_UNLOCK(&(REMOTE_ThreadHandle(wid).tlock)); | 
					
						
							| 
									
										
										
										
											2004-07-22 21:32:23 +00:00
										 |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-03-13 06:26:13 +00:00
										 |  |  | Int | 
					
						
							| 
									
										
										
										
											2004-07-22 21:32:23 +00:00
										 |  |  | Yap_thread_destroy_engine(int wid) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-12 08:34:26 +00:00
										 |  |  |   MUTEX_LOCK(&(REMOTE_ThreadHandle(wid).tlock)); | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  |   if (REMOTE_ThreadHandle(wid).ref_count == 0) { | 
					
						
							| 
									
										
										
										
											2008-08-06 17:32:22 +00:00
										 |  |  |     kill_thread_engine(wid, TRUE); | 
					
						
							| 
									
										
										
										
											2004-07-22 21:32:23 +00:00
										 |  |  |     return TRUE; | 
					
						
							|  |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2013-11-12 08:34:26 +00:00
										 |  |  |     MUTEX_UNLOCK(&(REMOTE_ThreadHandle(wid).tlock)); | 
					
						
							| 
									
										
										
										
											2004-07-22 21:32:23 +00:00
										 |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-08-11 16:14:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_thread_join( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2004-02-19 19:24:46 +00:00
										 |  |  |   Int tid = IntegerOfTerm(Deref(ARG1)); | 
					
						
							| 
									
										
										
										
											2014-10-19 01:54:57 +01:00
										 |  |  |   pthread_t thread; | 
					
						
							| 
									
										
										
										
											2004-02-19 19:24:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-19 01:54:57 +01:00
										 |  |  |   MUTEX_LOCK(&(REMOTE_ThreadHandle(tid).tlock)); | 
					
						
							|  |  |  |   if (!(REMOTE_ThreadHandle(tid).in_use || | 
					
						
							|  |  |  | 	REMOTE_ThreadHandle(tid).zombie)) { | 
					
						
							|  |  |  |     // he's dead, jim
 | 
					
						
							|  |  |  |     MUTEX_UNLOCK(&(REMOTE_ThreadHandle(tid).tlock)); | 
					
						
							| 
									
										
										
										
											2004-02-19 19:24:46 +00:00
										 |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  |   if (!REMOTE_ThreadHandle(tid).tdetach == MkAtomTerm(AtomTrue)) { | 
					
						
							| 
									
										
										
										
											2014-10-19 01:54:57 +01:00
										 |  |  |     MUTEX_UNLOCK(&(REMOTE_ThreadHandle(tid).tlock)); | 
					
						
							| 
									
										
										
										
											2004-02-19 19:24:46 +00:00
										 |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-10-19 01:54:57 +01:00
										 |  |  |   thread = REMOTE_ThreadHandle(tid).pthread_handle; | 
					
						
							|  |  |  |   MUTEX_UNLOCK(&(REMOTE_ThreadHandle(tid).tlock)); | 
					
						
							| 
									
										
										
										
											2004-12-02 06:06:47 +00:00
										 |  |  |   /* make sure this lock is accessible */ | 
					
						
							| 
									
										
										
										
											2014-10-19 01:54:57 +01:00
										 |  |  |   if (pthread_join(thread, NULL) < 0) { | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |     /* ERROR */ | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-19 19:24:46 +00:00
										 |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_thread_destroy( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2004-02-19 19:24:46 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   Int tid = IntegerOfTerm(Deref(ARG1)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-12 08:43:45 +00:00
										 |  |  |   MUTEX_LOCK(&(REMOTE_ThreadHandle(tid).tlock)); | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  |   REMOTE_ThreadHandle(tid).zombie = FALSE; | 
					
						
							|  |  |  |   REMOTE_ThreadHandle(tid).in_use = FALSE; | 
					
						
							| 
									
										
										
										
											2013-11-12 08:34:26 +00:00
										 |  |  |   MUTEX_UNLOCK(&(REMOTE_ThreadHandle(tid).tlock)); | 
					
						
							| 
									
										
										
										
											2004-02-19 19:24:46 +00:00
										 |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_thread_detach( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-03-26 14:41:45 +00:00
										 |  |  |   Int tid = IntegerOfTerm(Deref(ARG1)); | 
					
						
							| 
									
										
										
										
											2013-11-12 08:34:26 +00:00
										 |  |  |   MUTEX_LOCK(&(REMOTE_ThreadHandle(tid).tlock)); | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  |   if (pthread_detach(REMOTE_ThreadHandle(tid).pthread_handle) < 0) { | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |     /* ERROR */ | 
					
						
							| 
									
										
										
										
											2013-11-12 08:34:26 +00:00
										 |  |  |     MUTEX_UNLOCK(&(REMOTE_ThreadHandle(tid).tlock)); | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  |   REMOTE_ThreadHandle(tid).tdetach =  | 
					
						
							| 
									
										
										
										
											2008-03-26 14:41:45 +00:00
										 |  |  |     MkAtomTerm(AtomTrue); | 
					
						
							| 
									
										
										
										
											2013-11-12 08:34:26 +00:00
										 |  |  |   MUTEX_UNLOCK(&(REMOTE_ThreadHandle(tid).tlock)); | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-06 17:32:22 +00:00
										 |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_thread_detached( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2008-08-06 17:32:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-05-09 19:55:06 +01:00
										 |  |  |   if (LOCAL_ThreadHandle.tdetach) | 
					
						
							|  |  |  |     return Yap_unify(ARG1,LOCAL_ThreadHandle.tdetach); | 
					
						
							| 
									
										
										
										
											2008-08-08 16:05:10 +00:00
										 |  |  |   else | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_thread_detached2( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2008-08-08 16:05:10 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   Int tid = IntegerOfTerm(Deref(ARG1)); | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  |   if (REMOTE_ThreadHandle(tid).tdetach) | 
					
						
							|  |  |  |     return Yap_unify(ARG2,REMOTE_ThreadHandle(tid).tdetach); | 
					
						
							| 
									
										
										
										
											2008-08-08 16:05:10 +00:00
										 |  |  |   else | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2008-08-06 17:32:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_thread_exit( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-01-27 11:01:07 +00:00
										 |  |  |   thread_die(worker_id, FALSE);  | 
					
						
							| 
									
										
										
										
											2004-02-11 01:20:56 +00:00
										 |  |  |   pthread_exit(NULL); | 
					
						
							| 
									
										
										
										
											2008-08-08 14:05:34 +00:00
										 |  |  |   /* done, just make gcc happy */ | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_thread_set_concurrency( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-06-14 10:27:39 +01:00
										 |  |  | #if HAVE_PTHREAD_GETCONCURRENCY
 | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |   int newc;   | 
					
						
							|  |  |  |   int cur; | 
					
						
							|  |  |  |   Term tnew = Deref(ARG2);   | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   if (IsVarTerm(tnew)) { | 
					
						
							|  |  |  |     newc = 0; | 
					
						
							|  |  |  |   } else if (IsIntegerTerm(tnew)) { | 
					
						
							|  |  |  |     newc = IntegerOfTerm(tnew); | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     Yap_Error(TYPE_ERROR_INTEGER,tnew,"thread_set_concurrency/2"); | 
					
						
							|  |  |  |     return(FALSE); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   cur = MkIntegerTerm(pthread_getconcurrency()); | 
					
						
							|  |  |  |   if (pthread_setconcurrency(newc) != 0) { | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return Yap_unify(ARG1, MkIntegerTerm(cur)); | 
					
						
							| 
									
										
										
										
											2014-06-11 19:35:45 +01:00
										 |  |  | #else
 | 
					
						
							|  |  |  |   return FALSE; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-05-04 18:46:50 +00:00
										 |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_thread_yield( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2006-05-04 18:46:50 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   if (sched_yield() != 0) { | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | static Int | 
					
						
							| 
									
										
										
										
											2011-03-07 16:02:55 +00:00
										 |  |  | p_valid_thread( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   Int i = IntegerOfTerm(Deref(ARG1));  | 
					
						
							| 
									
										
										
										
											2011-05-09 20:19:49 +01:00
										 |  |  |   return REMOTE_ThreadHandle(i).in_use || REMOTE_ThreadHandle(i).zombie; | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Mutex Support */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct swi_mutex { | 
					
						
							|  |  |  |   UInt owners; | 
					
						
							|  |  |  |   Int tid_own; | 
					
						
							| 
									
										
										
										
											2014-11-27 10:02:04 +00:00
										 |  |  |   MutexEntry *alias; | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   pthread_mutex_t m; | 
					
						
							| 
									
										
										
										
											2014-11-27 10:02:04 +00:00
										 |  |  |   UInt timestamp; | 
					
						
							|  |  |  |   struct swi_mutex *backbone; // chain of all mutexes
 | 
					
						
							|  |  |  |   struct swi_mutex *prev, *next; // chain of locked mutexes
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | } SWIMutex; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-25 19:52:51 +00:00
										 |  |  | static SWIMutex *NewMutex(void) { | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   SWIMutex* mutp; | 
					
						
							|  |  |  |   pthread_mutexattr_t mat; | 
					
						
							| 
									
										
										
										
											2012-06-29 15:37:31 -05:00
										 |  |  | #if defined(HAVE_PTHREAD_MUTEXATTR_SETKIND_NP) && !defined(__MINGW32__)
 | 
					
						
							| 
									
										
										
										
											2011-06-06 10:32:58 +01:00
										 |  |  |   extern int pthread_mutexattr_setkind_np(pthread_mutexattr_t *attr, int kind); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-27 10:02:04 +00:00
										 |  |  |   LOCK(GLOBAL_MUT_ACCESS); | 
					
						
							|  |  |  |   mutp = GLOBAL_FreeMutexes; | 
					
						
							|  |  |  |   while (mutp) { | 
					
						
							|  |  |  |     if ((Int)(mutp->owners) < 0) { | 
					
						
							|  |  |  |       // just making sure
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     mutp = mutp->next; | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-11-27 10:02:04 +00:00
										 |  |  |   if (mutp == NULL) { | 
					
						
							|  |  |  |     mutp = (SWIMutex *)Yap_AllocCodeSpace(sizeof(SWIMutex)); | 
					
						
							|  |  |  |     if (mutp == NULL) { | 
					
						
							|  |  |  |       UNLOCK(GLOBAL_MUT_ACCESS); | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       pthread_mutexattr_init(&mat); | 
					
						
							|  |  |  |       mutp->timestamp = 0; | 
					
						
							| 
									
										
										
										
											2014-02-22 22:56:41 +00:00
										 |  |  | #if defined(HAVE_PTHREAD_MUTEXATTR_SETKIND_NP)  && !defined(__MINGW32__)
 | 
					
						
							| 
									
										
										
										
											2014-11-27 10:02:04 +00:00
										 |  |  |       pthread_mutexattr_setkind_np(&mat, PTHREAD_MUTEX_RECURSIVE_NP); | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | #ifdef HAVE_PTHREAD_MUTEXATTR_SETTYPE
 | 
					
						
							| 
									
										
										
										
											2014-11-27 10:02:04 +00:00
										 |  |  |       pthread_mutexattr_settype(&mat, PTHREAD_MUTEX_RECURSIVE); | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2014-11-27 10:02:04 +00:00
										 |  |  |       pthread_mutex_init(&mutp->m, &mat); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     mutp->backbone  = GLOBAL_mutex_backbone; | 
					
						
							|  |  |  |     GLOBAL_mutex_backbone = mutp; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     // reuse existing mutex
 | 
					
						
							|  |  |  |     mutp->timestamp++; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  |   mutp->owners = 0; | 
					
						
							| 
									
										
										
										
											2014-11-27 10:02:04 +00:00
										 |  |  |   mutp->tid_own = 0;   | 
					
						
							|  |  |  |   mutp->alias = NIL;   | 
					
						
							|  |  |  |   UNLOCK(GLOBAL_MUT_ACCESS); | 
					
						
							| 
									
										
										
										
											2014-11-25 19:52:51 +00:00
										 |  |  |   return mutp; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define MutexOfTerm(t) MutexOfTerm__(t PASS_REGS)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static SWIMutex *MutexOfTerm__(Term t USES_REGS){ | 
					
						
							|  |  |  |   Term t1 = Deref(t); | 
					
						
							|  |  |  |   SWIMutex *mut = NULL; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   if (IsVarTerm(t1)) { | 
					
						
							| 
									
										
										
										
											2014-11-27 10:02:04 +00:00
										 |  |  |     Yap_Error(INSTANTIATION_ERROR, t1, "mutex operation"); | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } else if (IsApplTerm(t1) && FunctorOfTerm(t1) == FunctorMutex) { | 
					
						
							|  |  |  |     mut = AddressOfTerm(ArgOfTerm(1,t1)); | 
					
						
							|  |  |  |     if ((Int)(mut->owners) < 0 || | 
					
						
							|  |  |  | 	IntegerOfTerm(ArgOfTerm(2,t1)) != mut->timestamp) { | 
					
						
							|  |  |  |       Yap_Error(EXISTENCE_ERROR_MUTEX,  t1, "mutex access"); | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-25 19:52:51 +00:00
										 |  |  |   } else if (IsAtomTerm(t1)) { | 
					
						
							|  |  |  |     mut = Yap_GetMutexFromProp(AtomOfTerm(t1)); | 
					
						
							| 
									
										
										
										
											2014-11-26 09:45:39 +00:00
										 |  |  |     if (!mut) { | 
					
						
							|  |  |  |       mut = NewMutex(); | 
					
						
							|  |  |  |       if ( !Yap_PutAtomMutex( AtomOfTerm(t1), mut ) ) { | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-11-25 19:52:51 +00:00
										 |  |  |   } | 
					
						
							|  |  |  |   return mut; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int | 
					
						
							|  |  |  | p_new_mutex( USES_REGS1 ){ | 
					
						
							|  |  |  |   SWIMutex* mutp; | 
					
						
							|  |  |  |   Term t1; | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |   if (IsVarTerm((t1 = Deref(ARG1)))) { | 
					
						
							| 
									
										
										
										
											2014-11-27 10:02:04 +00:00
										 |  |  |     Term ts[2]; | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2014-11-25 19:52:51 +00:00
										 |  |  |     if (!(mutp = NewMutex())) | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							| 
									
										
										
										
											2014-11-27 10:02:04 +00:00
										 |  |  |     ts[0] = MkAddressTerm(mutp);     | 
					
						
							|  |  |  |     ts[1] = MkIntegerTerm(mutp->timestamp);     | 
					
						
							|  |  |  |     if (Yap_unify(ARG1, Yap_MkApplTerm(FunctorMutex, 2, ts) ) ) { | 
					
						
							|  |  |  |       return TRUE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     Yap_Error(UNINSTANTIATION_ERROR, t1, "mutex_create on an existing mutex"); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |   } else if(IsAtomTerm(t1)) { | 
					
						
							| 
									
										
										
										
											2014-11-26 09:45:39 +00:00
										 |  |  |     if (!(mutp = NewMutex())) | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |     return Yap_PutAtomMutex( AtomOfTerm(t1), mutp ); | 
					
						
							| 
									
										
										
										
											2014-11-27 10:02:04 +00:00
										 |  |  |   } else if (IsApplTerm(t1)  && FunctorOfTerm(t1) == FunctorMutex) { | 
					
						
							|  |  |  |     Yap_Error(UNINSTANTIATION_ERROR, t1, "mutex_create on an existing mutex"); | 
					
						
							| 
									
										
										
										
											2014-11-25 19:52:51 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-11-25 19:52:51 +00:00
										 |  |  |   return FALSE; | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-11-25 19:52:51 +00:00
										 |  |  |    | 
					
						
							| 
									
										
										
										
											2014-11-27 10:02:04 +00:00
										 |  |  | /** @pred mutex_destroy(+ _MutexId_)
 | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     Destroy a mutex.  After this call,  _MutexId_ becomes invalid and | 
					
						
							|  |  |  |     further references yield an `existence_error` exception.  | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | static Int p_destroy_mutex( USES_REGS1 ) | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-11-25 19:52:51 +00:00
										 |  |  |   SWIMutex *mut = MutexOfTerm(Deref(ARG1)); | 
					
						
							|  |  |  |   if (!mut) | 
					
						
							| 
									
										
										
										
											2014-11-26 09:45:39 +00:00
										 |  |  |     return FALSE;   | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |   if (pthread_mutex_destroy(&mut->m) < 0) | 
					
						
							| 
									
										
										
										
											2014-11-27 10:02:04 +00:00
										 |  |  |      return FALSE; | 
					
						
							|  |  |  |   if (mut->alias) { | 
					
						
							|  |  |  |     mut->alias->Mutex  = NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   mut->owners = -1; | 
					
						
							|  |  |  |   mut->tid_own = -1; | 
					
						
							|  |  |  |   LOCK(GLOBAL_MUT_ACCESS); | 
					
						
							|  |  |  |   if (GLOBAL_FreeMutexes) | 
					
						
							|  |  |  |     mut->prev = GLOBAL_FreeMutexes->prev; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     mut->prev = NULL; | 
					
						
							|  |  |  |   mut->next = GLOBAL_FreeMutexes; | 
					
						
							|  |  |  |   GLOBAL_FreeMutexes = mut; | 
					
						
							|  |  |  |   UNLOCK(GLOBAL_MUT_ACCESS); | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-26 09:45:39 +00:00
										 |  |  | static bool | 
					
						
							|  |  |  | LockMutex( SWIMutex *mut USES_REGS) | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  | { | 
					
						
							|  |  |  | #if DEBUG_LOCKS
 | 
					
						
							|  |  |  |   MUTEX_LOCK(&mut->m); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   if (MUTEX_LOCK(&mut->m) < 0) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   mut->owners++; | 
					
						
							|  |  |  |   mut->tid_own = worker_id; | 
					
						
							| 
									
										
										
										
											2014-11-27 10:02:04 +00:00
										 |  |  |   if (LOCAL_Mutexes) | 
					
						
							|  |  |  |     mut->prev = LOCAL_Mutexes->prev; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     mut->prev = NULL; | 
					
						
							|  |  |  |   mut->next = LOCAL_Mutexes; | 
					
						
							|  |  |  |   LOCAL_Mutexes = NULL; | 
					
						
							| 
									
										
										
										
											2014-11-26 09:45:39 +00:00
										 |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static bool | 
					
						
							| 
									
										
										
										
											2014-11-27 10:02:04 +00:00
										 |  |  | UnLockMutex( SWIMutex *mut USES_REGS) | 
					
						
							| 
									
										
										
										
											2014-11-26 09:45:39 +00:00
										 |  |  | { | 
					
						
							|  |  |  | #if DEBUG_LOCKS
 | 
					
						
							|  |  |  |   MUTEX_UNLOCK(&mut->m); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   if (MUTEX_UNLOCK(&mut->m) < 0) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   mut->owners--; | 
					
						
							| 
									
										
										
										
											2014-11-27 10:02:04 +00:00
										 |  |  |   if (mut->prev) { | 
					
						
							|  |  |  |     mut->prev->next = mut->next; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     LOCAL_Mutexes = mut->next; | 
					
						
							|  |  |  |     if (mut->next) | 
					
						
							|  |  |  |       mut->next->prev = NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (mut->next) | 
					
						
							|  |  |  |     mut->next->prev = mut->prev; | 
					
						
							| 
									
										
										
										
											2014-11-26 09:45:39 +00:00
										 |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-27 10:02:04 +00:00
										 |  |  | /** @pred mutex_lock(+ _MutexId_) 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Lock the mutex.  Prolog mutexes are <em>recursive</em> mutexes: they | 
					
						
							|  |  |  |     can be locked multiple times by the same thread.  Only after unlocking | 
					
						
							|  |  |  |     it as many times as it is locked, the mutex becomes available for | 
					
						
							|  |  |  |     locking by other threads. If another thread has locked the mutex the | 
					
						
							|  |  |  |     calling thread is suspended until to mutex is unlocked. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     If  _MutexId_ is an atom, and there is no current mutex with that | 
					
						
							|  |  |  |     name, the mutex is created automatically using mutex_create/1.  This | 
					
						
							|  |  |  |     implies named mutexes need not be declared explicitly. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Please note that locking and unlocking mutexes should be paired | 
					
						
							|  |  |  |     carefully. Especially make sure to unlock mutexes even if the protected | 
					
						
							|  |  |  |     code fails or raises an exception. For most common cases use | 
					
						
							|  |  |  |     with_mutex/2, which provides a safer way for handling Prolog-level | 
					
						
							|  |  |  |     mutexes. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2014-11-26 09:45:39 +00:00
										 |  |  | static Int | 
					
						
							|  |  |  | p_lock_mutex( USES_REGS1 ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   SWIMutex *mut = MutexOfTerm(Deref(ARG1)); | 
					
						
							|  |  |  |   if (!mut || !LockMutex( mut PASS_REGS)) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-27 10:02:04 +00:00
										 |  |  | /** @pred mutex_trylock(+ _MutexId_) 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     As mutex_lock/1, but if the mutex is held by another thread, this | 
					
						
							|  |  |  |     predicates fails immediately. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  | static Int | 
					
						
							|  |  |  | p_trylock_mutex( USES_REGS1 ) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-11-25 19:52:51 +00:00
										 |  |  |   SWIMutex *mut = MutexOfTerm(Deref(ARG1)); | 
					
						
							|  |  |  |   if (!mut) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |    | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |   if (MUTEX_TRYLOCK(&mut->m) == EBUSY) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   mut->owners++; | 
					
						
							|  |  |  |   mut->tid_own = worker_id; | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-27 10:02:04 +00:00
										 |  |  | /** @pred mutex_unlock(+ _MutexId_) 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Unlock the mutex. This can only be called if the mutex is held by the | 
					
						
							|  |  |  |     calling thread. If this is not the case, a `permission_error` | 
					
						
							|  |  |  |     exception is raised. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  | static Int | 
					
						
							|  |  |  | p_unlock_mutex( USES_REGS1 ) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-11-25 19:52:51 +00:00
										 |  |  |   SWIMutex *mut = MutexOfTerm(Deref(ARG1)); | 
					
						
							| 
									
										
										
										
											2014-11-27 10:02:04 +00:00
										 |  |  |   if (!mut || !UnLockMutex( mut PASS_REGS)) | 
					
						
							| 
									
										
										
										
											2014-11-25 19:52:51 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-27 10:02:04 +00:00
										 |  |  | /** @pred with_mutex(+ _MutexId_, : _Goal_) 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Execute  _Goal_ while holding  _MutexId_.  If  _Goal_ leaves | 
					
						
							|  |  |  |     choicepoints, these are destroyed (as in once/1).  The mutex is unlocked | 
					
						
							|  |  |  |     regardless of whether  _Goal_ succeeds, fails or raises an exception. | 
					
						
							|  |  |  |     An exception thrown by  _Goal_ is re-thrown after the mutex has been | 
					
						
							|  |  |  |     successfully unlocked.  See also `mutex_create/2`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Although described in the thread-section, this predicate is also | 
					
						
							|  |  |  |     available in the single-threaded version, where it behaves simply as | 
					
						
							|  |  |  |     once/1. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  | static Int | 
					
						
							|  |  |  | p_with_mutex( USES_REGS1 ) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-11-26 09:45:39 +00:00
										 |  |  |   Term excep; | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |   Int rc = FALSE; | 
					
						
							|  |  |  |   Int creeping = Yap_get_signal(YAP_CREEP_SIGNAL); | 
					
						
							|  |  |  |   PredEntry *pe; | 
					
						
							|  |  |  |   Term tm = CurrentModule; | 
					
						
							|  |  |  |   Term tg = Deref(ARG2); | 
					
						
							| 
									
										
										
										
											2014-11-26 09:45:39 +00:00
										 |  |  |   SWIMutex *mut = MutexOfTerm( ARG1 ); | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-26 09:45:39 +00:00
										 |  |  |   if (!mut || !LockMutex(mut PASS_REGS)) { | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   tg = Yap_StripModule(tg, &tm); | 
					
						
							|  |  |  |   if (IsVarTerm(tg)) { | 
					
						
							|  |  |  |     Yap_Error(INSTANTIATION_ERROR, ARG2, "with_mutex/2"); | 
					
						
							|  |  |  |     goto end; | 
					
						
							|  |  |  |   } else if (IsApplTerm(tg)) { | 
					
						
							|  |  |  |     register Functor f = FunctorOfTerm(tg); | 
					
						
							|  |  |  |     register CELL *pt; | 
					
						
							|  |  |  |     size_t i, arity; | 
					
						
							| 
									
										
										
										
											2014-11-09 17:26:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     f = FunctorOfTerm(tg); | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |     if (IsExtensionFunctor(f)) { | 
					
						
							|  |  |  |       Yap_Error(TYPE_ERROR_CALLABLE, tg, "with_mutex/2"); | 
					
						
							|  |  |  |       goto end; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     arity = ArityOfFunctor(f); | 
					
						
							|  |  |  |     if (arity > MaxTemps) { | 
					
						
							|  |  |  |       Yap_Error(TYPE_ERROR_CALLABLE, tg, "with_mutex/2"); | 
					
						
							|  |  |  |       goto end; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     pe = RepPredProp(PredPropByFunc(f, tm)); | 
					
						
							|  |  |  |     pt = RepAppl(tg)+1; | 
					
						
							|  |  |  |     for (i= 0; i < arity; i++ ) | 
					
						
							|  |  |  |       XREGS[i+1] = pt[i]; | 
					
						
							|  |  |  |   } else if (IsAtomTerm(tg)) { | 
					
						
							|  |  |  |     pe = RepPredProp(PredPropByAtom(AtomOfTerm(tg), tm)); | 
					
						
							|  |  |  |   } else if (IsPairTerm(tg)) { | 
					
						
							|  |  |  |     register CELL *pt; | 
					
						
							|  |  |  |     Functor f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     f = FunctorDot; | 
					
						
							|  |  |  |     pe = RepPredProp(PredPropByFunc(f, tm)); | 
					
						
							|  |  |  |     pt = RepPair(tg); | 
					
						
							|  |  |  |     XREGS[1] = pt[0]; | 
					
						
							|  |  |  |     XREGS[2] = pt[1]; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     Yap_Error(TYPE_ERROR_CALLABLE, tg, "with_mutex/2"); | 
					
						
							|  |  |  |     goto end; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if ( | 
					
						
							|  |  |  |       pe->OpcodeOfPred != FAIL_OPCODE && | 
					
						
							| 
									
										
										
										
											2015-06-19 01:30:13 +01:00
										 |  |  |       Yap_execute_pred(pe, NULL, true PASS_REGS) ) { | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |     rc = TRUE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |  end: | 
					
						
							|  |  |  |   excep = Yap_GetException(); | 
					
						
							| 
									
										
										
										
											2014-11-27 10:02:04 +00:00
										 |  |  |   if ( !UnLockMutex(mut PASS_REGS) ) { | 
					
						
							| 
									
										
										
										
											2014-11-26 09:45:39 +00:00
										 |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |   if (creeping) { | 
					
						
							|  |  |  |     Yap_signal( YAP_CREEP_SIGNAL ); | 
					
						
							|  |  |  |   } else if ( excep != 0) { | 
					
						
							|  |  |  |     return Yap_JumpToEnv(excep); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return rc; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int | 
					
						
							|  |  |  | p_with_with_mutex( USES_REGS1 ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (GLOBAL_WithMutex == NULL) { | 
					
						
							|  |  |  |     p_new_mutex( PASS_REGS1 ); | 
					
						
							|  |  |  |     GLOBAL_WithMutex = (SWIMutex*)IntegerOfTerm(Deref(ARG1)); | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     ARG1 = MkIntegerTerm((Int)GLOBAL_WithMutex); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return p_lock_mutex( PASS_REGS1 ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int | 
					
						
							|  |  |  | p_unlock_with_mutex( USES_REGS1 ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   ARG1 = MkIntegerTerm((Int)GLOBAL_WithMutex); | 
					
						
							|  |  |  |   return p_unlock_mutex( PASS_REGS1 ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int | 
					
						
							|  |  |  | p_mutex_info( USES_REGS1 ) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2014-11-25 19:52:51 +00:00
										 |  |  |   SWIMutex *mut = MutexOfTerm(Deref(ARG1)); | 
					
						
							|  |  |  |   if (!mut) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return Yap_unify(ARG2, MkIntegerTerm(mut->owners)) && | 
					
						
							|  |  |  |     Yap_unify(ARG3, MkIntegerTerm(mut->tid_own)); | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  |   UInt indx; | 
					
						
							|  |  |  |   mbox_t mbox; | 
					
						
							|  |  |  | } counted_mbox; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-09 17:26:08 +00:00
										 |  |  |  static Int | 
					
						
							|  |  |  |  p_mbox_create( USES_REGS1 ) | 
					
						
							|  |  |  |  { | 
					
						
							|  |  |  |    Term namet = Deref(ARG1); | 
					
						
							|  |  |  |    mbox_t* mboxp = GLOBAL_named_mboxes; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    if (IsVarTerm(namet)) { | 
					
						
							|  |  |  |        AtomEntry *ae; | 
					
						
							|  |  |  |        int new; | 
					
						
							|  |  |  |        mbox_t mbox; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        ae = Yap_lookupBlob(&mbox, sizeof(mbox), &PL_Message_Queue, &new); | 
					
						
							|  |  |  |        namet = MkAtomTerm(RepAtom(ae)); | 
					
						
							|  |  |  |        mboxp = (mbox_t *)(ae->rep.blob[0].data); | 
					
						
							|  |  |  |       Yap_unify(ARG1, namet); | 
					
						
							|  |  |  |       LOCK(GLOBAL_mboxq_lock); | 
					
						
							|  |  |  |    } else if (IsAtomTerm(namet)) { | 
					
						
							|  |  |  |        LOCK(GLOBAL_mboxq_lock); | 
					
						
							|  |  |  |        while( mboxp && mboxp->name != namet) | 
					
						
							|  |  |  | 	 mboxp = mboxp->next; | 
					
						
							|  |  |  |        if (mboxp) { | 
					
						
							|  |  |  | 	   UNLOCK(GLOBAL_mboxq_lock); | 
					
						
							|  |  |  | 	   return FALSE; | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |        mboxp = (mbox_t *)Yap_AllocCodeSpace(sizeof(mbox_t)); | 
					
						
							|  |  |  |        if (mboxp == NULL) { | 
					
						
							|  |  |  | 	   UNLOCK(GLOBAL_mboxq_lock); | 
					
						
							|  |  |  | 	   return FALSE; | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |        // global mbox, for now we'll just insert in list
 | 
					
						
							|  |  |  |        mboxp->next = GLOBAL_named_mboxes; | 
					
						
							|  |  |  |        GLOBAL_named_mboxes = mboxp; | 
					
						
							|  |  |  |    } | 
					
						
							|  |  |  |    bool rc = mboxCreate( namet, mboxp PASS_REGS ); | 
					
						
							|  |  |  |    UNLOCK(GLOBAL_mboxq_lock); | 
					
						
							|  |  |  |    return rc; | 
					
						
							|  |  |  |  } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static Int | 
					
						
							|  |  |  | p_mbox_destroy( USES_REGS1 ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   Term namet = Deref(ARG1); | 
					
						
							|  |  |  |   mbox_t* mboxp = GLOBAL_named_mboxes, *prevp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (IsVarTerm(namet) ) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   if (IsIntTerm(namet) ) { | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   LOCK(GLOBAL_mboxq_lock); | 
					
						
							|  |  |  |   prevp = NULL; | 
					
						
							|  |  |  |   while( mboxp && mboxp->name != namet) { | 
					
						
							|  |  |  |     prevp = mboxp; | 
					
						
							|  |  |  |     mboxp = mboxp->next; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (!mboxp) { | 
					
						
							|  |  |  |     UNLOCK(GLOBAL_mboxq_lock); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (mboxp == GLOBAL_named_mboxes) { | 
					
						
							|  |  |  |     GLOBAL_named_mboxes = mboxp->next; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     prevp->next = mboxp->next; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   UNLOCK(GLOBAL_mboxq_lock); | 
					
						
							|  |  |  |   mboxDestroy(mboxp PASS_REGS); | 
					
						
							|  |  |  |   Yap_FreeCodeSpace( (char *)mboxp ); | 
					
						
							| 
									
										
										
										
											2014-11-09 17:26:08 +00:00
										 |  |  |    return TRUE; | 
					
						
							|  |  |  |  } | 
					
						
							| 
									
										
										
										
											2014-10-14 15:53:24 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-09 17:26:08 +00:00
										 |  |  |  static mbox_t* | 
					
						
							|  |  |  |  getMbox(Term t) | 
					
						
							|  |  |  |  { | 
					
						
							|  |  |  |    mbox_t* mboxp; | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-09 17:26:08 +00:00
										 |  |  |    if (IsAtomTerm(t=Deref(t))) { | 
					
						
							|  |  |  |      Atom at = AtomOfTerm(t); | 
					
						
							|  |  |  |      LOCK(GLOBAL_mboxq_lock); | 
					
						
							|  |  |  |      if (IsBlob(at)) { | 
					
						
							|  |  |  |        mboxp = (mbox_t *)(RepAtom(at)->rep.blob[0].data); | 
					
						
							|  |  |  |      } else { | 
					
						
							|  |  |  |        mboxp = GLOBAL_named_mboxes; | 
					
						
							|  |  |  |        while( mboxp && mboxp->name != t) { | 
					
						
							|  |  |  | 	   mboxp = mboxp->next; | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |      } | 
					
						
							|  |  |  |      if (!mboxp->open) | 
					
						
							|  |  |  |        mboxp = NULL; | 
					
						
							|  |  |  |      if (mboxp) { | 
					
						
							|  |  |  | 	 pthread_mutex_lock(& mboxp->mutex); | 
					
						
							|  |  |  |      } | 
					
						
							|  |  |  |      UNLOCK(GLOBAL_mboxq_lock); | 
					
						
							|  |  |  |    } else if (IsIntTerm(t)) { | 
					
						
							|  |  |  |        int wid = IntOfTerm(t); | 
					
						
							|  |  |  |        if (REMOTE(wid) && | 
					
						
							|  |  |  | 	   (REMOTE_ThreadHandle(wid).in_use || REMOTE_ThreadHandle(wid).zombie)) | 
					
						
							|  |  |  |        { | 
					
						
							|  |  |  | 	 return &REMOTE_ThreadHandle(wid).mbox_handle; | 
					
						
							|  |  |  |        } else { | 
					
						
							|  |  |  | 	  return NULL; | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |        if (!mboxp->open) | 
					
						
							|  |  |  | 	 mboxp = NULL; | 
					
						
							|  |  |  |        if (mboxp) { | 
					
						
							|  |  |  | 	   pthread_mutex_lock(& mboxp->mutex); | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |    } else { | 
					
						
							|  |  |  |        return NULL; | 
					
						
							|  |  |  |    } | 
					
						
							|  |  |  |    return mboxp; | 
					
						
							|  |  |  |  } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  static Int | 
					
						
							|  |  |  |  p_mbox_send( USES_REGS1 ) | 
					
						
							|  |  |  |  { | 
					
						
							|  |  |  |    Term namet = Deref(ARG1); | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |    mbox_t* mboxp = getMbox(namet) ; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-14 15:53:24 +01:00
										 |  |  |    if (!mboxp) | 
					
						
							| 
									
										
										
										
											2014-11-09 17:26:08 +00:00
										 |  |  |      return FALSE; | 
					
						
							|  |  |  |    return mboxSend(mboxp, Deref(ARG2) PASS_REGS); | 
					
						
							|  |  |  |  } | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-09 17:26:08 +00:00
										 |  |  |  static Int | 
					
						
							|  |  |  |  p_mbox_size( USES_REGS1 ) | 
					
						
							|  |  |  |  { | 
					
						
							|  |  |  |    Term namet = Deref(ARG1); | 
					
						
							| 
									
										
										
										
											2014-10-13 12:34:52 +01:00
										 |  |  |    mbox_t* mboxp = getMbox(namet) ; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-14 15:53:24 +01:00
										 |  |  |    if (!mboxp) | 
					
						
							| 
									
										
										
										
											2014-11-09 17:26:08 +00:00
										 |  |  |      return FALSE; | 
					
						
							|  |  |  |    return Yap_unify( ARG2, MkIntTerm(mboxp->nmsgs)); | 
					
						
							|  |  |  |  } | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-09 17:26:08 +00:00
										 |  |  |  static Int | 
					
						
							|  |  |  |  p_mbox_receive( USES_REGS1 ) | 
					
						
							|  |  |  |  { | 
					
						
							|  |  |  |    Term namet = Deref(ARG1); | 
					
						
							|  |  |  |     mbox_t* mboxp = getMbox(namet) ; | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-09 17:26:08 +00:00
										 |  |  |     if (!mboxp) | 
					
						
							|  |  |  |        return FALSE; | 
					
						
							|  |  |  |    return mboxReceive(mboxp, Deref(ARG2) PASS_REGS); | 
					
						
							|  |  |  |  } | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-07 20:51:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-09 17:26:08 +00:00
										 |  |  |  static Int | 
					
						
							|  |  |  |  p_mbox_peek( USES_REGS1 ) | 
					
						
							|  |  |  |  { | 
					
						
							|  |  |  |    Term namet = Deref(ARG1); | 
					
						
							|  |  |  |     mbox_t* mboxp = getMbox(namet) ; | 
					
						
							| 
									
										
										
										
											2008-08-07 20:51:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-09 17:26:08 +00:00
										 |  |  |     if (!mboxp) | 
					
						
							|  |  |  |        return FALSE; | 
					
						
							|  |  |  |    return mboxPeek(mboxp, Deref(ARG2) PASS_REGS); | 
					
						
							|  |  |  |  } | 
					
						
							| 
									
										
										
										
											2008-08-07 20:51:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-25 19:52:51 +00:00
										 |  |  | static Int | 
					
						
							|  |  |  | p_cond_create( USES_REGS1 ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   pthread_cond_t* condp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   condp = (pthread_cond_t *)Yap_AllocCodeSpace(sizeof(pthread_cond_t)); | 
					
						
							|  |  |  |   if (condp == NULL) { | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   pthread_cond_init(condp, NULL); | 
					
						
							|  |  |  |   return Yap_unify(ARG1, MkIntegerTerm((Int)condp)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int | 
					
						
							| 
									
										
										
										
											2014-11-09 17:26:08 +00:00
										 |  |  |  p_cond_destroy( USES_REGS1 ) | 
					
						
							|  |  |  |  { | 
					
						
							|  |  |  |    pthread_cond_t *condp = (pthread_cond_t *)IntegerOfTerm(Deref(ARG1)); | 
					
						
							| 
									
										
										
										
											2008-08-07 20:51:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-09 17:26:08 +00:00
										 |  |  |    if (pthread_cond_destroy(condp) < 0) | 
					
						
							|  |  |  |      return FALSE; | 
					
						
							|  |  |  |    Yap_FreeCodeSpace((void *)condp); | 
					
						
							| 
									
										
										
										
											2008-05-28 17:18:35 +00:00
										 |  |  |    return TRUE; | 
					
						
							| 
									
										
										
										
											2014-11-09 17:26:08 +00:00
										 |  |  |  } | 
					
						
							| 
									
										
										
										
											2013-11-13 10:38:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-09 17:26:08 +00:00
										 |  |  |  static Int | 
					
						
							|  |  |  |  p_cond_signal( USES_REGS1 ) | 
					
						
							|  |  |  |  { | 
					
						
							|  |  |  |    pthread_cond_t *condp = (pthread_cond_t *)IntegerOfTerm(Deref(ARG1)); | 
					
						
							| 
									
										
										
										
											2013-11-13 10:38:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-09 17:26:08 +00:00
										 |  |  |    if (pthread_cond_signal(condp) < 0) | 
					
						
							|  |  |  |      return FALSE; | 
					
						
							|  |  |  |    return TRUE; | 
					
						
							|  |  |  |  } | 
					
						
							| 
									
										
										
										
											2014-06-04 22:08:37 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-09 17:26:08 +00:00
										 |  |  |  static Int | 
					
						
							|  |  |  |  p_cond_broadcast( USES_REGS1 ) | 
					
						
							|  |  |  |  { | 
					
						
							|  |  |  |    pthread_cond_t *condp = (pthread_cond_t *)IntegerOfTerm(Deref(ARG1)); | 
					
						
							| 
									
										
										
										
											2014-06-04 22:08:37 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-09 17:26:08 +00:00
										 |  |  |    if (pthread_cond_broadcast(condp) < 0) | 
					
						
							|  |  |  |      return FALSE; | 
					
						
							| 
									
										
										
										
											2014-11-25 12:03:48 +00:00
										 |  |  |    return TRUE; | 
					
						
							| 
									
										
										
										
											2014-11-09 17:26:08 +00:00
										 |  |  |  } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  static Int | 
					
						
							|  |  |  |  p_cond_wait( USES_REGS1 ) | 
					
						
							|  |  |  |  { | 
					
						
							|  |  |  |    pthread_cond_t *condp = (pthread_cond_t *)IntegerOfTerm(Deref(ARG1)); | 
					
						
							|  |  |  |    SWIMutex *mut = (SWIMutex*)IntegerOfTerm(Deref(ARG2)); | 
					
						
							|  |  |  |    pthread_cond_wait(condp, &mut->m); | 
					
						
							| 
									
										
										
										
											2014-11-25 16:53:35 +00:00
										 |  |  |    return TRUE; | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							|  |  |  | p_thread_stacks( USES_REGS1 ) | 
					
						
							|  |  |  | {				/* '$thread_signal'(+P)	 */ | 
					
						
							|  |  |  |   Int tid = IntegerOfTerm(Deref(ARG1)); | 
					
						
							|  |  |  |   Int status= TRUE; | 
					
						
							| 
									
										
										
										
											2007-01-29 10:18:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |   MUTEX_LOCK(&(REMOTE_ThreadHandle(tid).tlock)); | 
					
						
							|  |  |  |   if (REMOTE(tid) && | 
					
						
							|  |  |  |       (REMOTE_ThreadHandle(tid).in_use || REMOTE_ThreadHandle(tid).zombie)) { | 
					
						
							|  |  |  |     status &= Yap_unify(ARG2,MkIntegerTerm(REMOTE_ThreadHandle(tid).ssize)); | 
					
						
							|  |  |  |     status &= Yap_unify(ARG3,MkIntegerTerm(REMOTE_ThreadHandle(tid).tsize)); | 
					
						
							|  |  |  |     status &= Yap_unify(ARG4,MkIntegerTerm(REMOTE_ThreadHandle(tid).sysize)); | 
					
						
							|  |  |  |     MUTEX_UNLOCK(&(REMOTE_ThreadHandle(tid).tlock)); | 
					
						
							|  |  |  |     return status; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   MUTEX_UNLOCK(&(REMOTE_ThreadHandle(tid).tlock)); | 
					
						
							|  |  |  |   return FALSE; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2004-03-02 16:44:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  | static Int  | 
					
						
							|  |  |  | p_thread_atexit( USES_REGS1 ) | 
					
						
							|  |  |  | {				/* '$thread_signal'(+P)	 */ | 
					
						
							|  |  |  |   Term t; | 
					
						
							| 
									
										
										
										
											2004-03-02 16:44:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |   if (LOCAL_ThreadHandle.texit == NULL || | 
					
						
							|  |  |  |       LOCAL_ThreadHandle.texit->Entry == MkAtomTerm(AtomTrue)) { | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   do { | 
					
						
							|  |  |  |     t = Yap_PopTermFromDB(LOCAL_ThreadHandle.texit); | 
					
						
							|  |  |  |     if (t == 0) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  |       if (LOCAL_Error_TYPE == RESOURCE_ERROR_ATTRIBUTED_VARIABLES) { | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  | 	LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							|  |  |  | 	if (!Yap_growglobal(NULL)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 	  Yap_Error(RESOURCE_ERROR_ATTRIBUTED_VARIABLES, TermNil, LOCAL_ErrorMessage); | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  | 	  thread_die(worker_id, FALSE); | 
					
						
							|  |  |  | 	  return FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  | 	LOCAL_Error_TYPE = YAP_NO_ERROR; | 
					
						
							|  |  |  | 	if (!Yap_growstack(LOCAL_ThreadHandle.tgoal->NOfCells*CellSize)) { | 
					
						
							| 
									
										
										
										
											2015-09-25 10:57:26 +01:00
										 |  |  | 	  Yap_Error(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage); | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  | 	  thread_die(worker_id, FALSE); | 
					
						
							|  |  |  | 	  return FALSE; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } while (t == 0); | 
					
						
							|  |  |  |   LOCAL_ThreadHandle.texit = NULL; | 
					
						
							|  |  |  |   return Yap_unify(ARG1, t) && Yap_unify(ARG2, LOCAL_ThreadHandle.texit_mod); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-02-22 15:08:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							|  |  |  | p_thread_signal( USES_REGS1 ) | 
					
						
							|  |  |  | {				/* '$thread_signal'(+P)	 */ | 
					
						
							|  |  |  |   Int wid = IntegerOfTerm(Deref(ARG1)); | 
					
						
							|  |  |  |   /* make sure the lock is available */ | 
					
						
							|  |  |  |   MUTEX_LOCK(&(REMOTE_ThreadHandle(wid).tlock)); | 
					
						
							|  |  |  |   if (!REMOTE_ThreadHandle(wid).in_use ||  | 
					
						
							|  |  |  |       !REMOTE_ThreadHandle(wid).current_yaam_regs) { | 
					
						
							|  |  |  |     MUTEX_UNLOCK(&(REMOTE_ThreadHandle(wid).tlock)); | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   Yap_external_signal( wid,  YAP_ITI_SIGNAL ); | 
					
						
							|  |  |  |   MUTEX_UNLOCK(&(REMOTE_ThreadHandle(wid).tlock)); | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							|  |  |  | p_no_threads( USES_REGS1 ) | 
					
						
							|  |  |  | {				/* '$thread_signal'(+P)	 */ | 
					
						
							|  |  |  |   return FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							|  |  |  | p_nof_threads( USES_REGS1 ) | 
					
						
							|  |  |  | {				/* '$nof_threads'(+P)	 */ | 
					
						
							|  |  |  |   int i = 0, wid; | 
					
						
							|  |  |  |   LOCK(GLOBAL_ThreadHandlesLock); | 
					
						
							|  |  |  |   for (wid = 0; wid < MAX_THREADS; wid++) { | 
					
						
							|  |  |  |     if (!Yap_local[wid]) break; | 
					
						
							|  |  |  |     if (REMOTE_ThreadHandle(wid).in_use) | 
					
						
							|  |  |  |       i++; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   UNLOCK(GLOBAL_ThreadHandlesLock); | 
					
						
							|  |  |  |   return Yap_unify(ARG1,MkIntegerTerm(i)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							|  |  |  | p_max_workers( USES_REGS1 ) | 
					
						
							|  |  |  | {				/* '$max_workers'(+P)	 */ | 
					
						
							|  |  |  |   return Yap_unify(ARG1,MkIntegerTerm(MAX_WORKERS)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							|  |  |  | p_max_threads( USES_REGS1 ) | 
					
						
							|  |  |  | {				/* '$max_threads'(+P)	 */ | 
					
						
							|  |  |  |   return Yap_unify(ARG1,MkIntegerTerm(MAX_THREADS)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							|  |  |  | p_nof_threads_created( USES_REGS1 ) | 
					
						
							|  |  |  | {				/* '$nof_threads'(+P)	 */ | 
					
						
							|  |  |  |   return Yap_unify(ARG1,MkIntTerm(GLOBAL_NOfThreadsCreated)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							|  |  |  | p_thread_runtime( USES_REGS1 ) | 
					
						
							|  |  |  | {				/* '$thread_runtime'(+P)	 */ | 
					
						
							|  |  |  |   return Yap_unify(ARG1,MkIntegerTerm(GLOBAL_ThreadsTotalTime)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							|  |  |  | p_thread_self_lock( USES_REGS1 ) | 
					
						
							|  |  |  | {				/* '$thread_unlock'	 */ | 
					
						
							|  |  |  |   MUTEX_LOCK(&(LOCAL_ThreadHandle.tlock)); | 
					
						
							|  |  |  |   return Yap_unify(ARG1,MkIntegerTerm(worker_id)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							|  |  |  | p_thread_unlock( USES_REGS1 ) | 
					
						
							|  |  |  | {				/* '$thread_unlock'	 */ | 
					
						
							|  |  |  |   Int wid = IntegerOfTerm(Deref(ARG1)); | 
					
						
							|  |  |  |   MUTEX_UNLOCK(&(REMOTE_ThreadHandle(wid).tlock)); | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | intptr_t | 
					
						
							| 
									
										
										
										
											2015-06-19 01:30:13 +01:00
										 |  |  | system_thread_id(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | #if defined(__APPLE__)
 | 
					
						
							|  |  |  |   return      syscall(SYS_thread_selfid); | 
					
						
							|  |  |  | #elif HAVE_SYS_GETTID || defined(__APPLE__)
 | 
					
						
							| 
									
										
										
										
											2015-10-09 10:31:52 +01:00
										 |  |  |   return syscall( SYS_GETTID ); | 
					
						
							| 
									
										
										
										
											2015-10-05 10:30:17 +01:00
										 |  |  | #elif HAVE_GETTID_SYSCALL
 | 
					
						
							| 
									
										
										
										
											2015-06-19 01:30:13 +01:00
										 |  |  |     return syscall(__NR_gettid); | 
					
						
							|  |  |  | #elif defined( HAVE_GETTID_MACRO )
 | 
					
						
							|  |  |  |     return gettid(); | 
					
						
							|  |  |  | #elif  defined(__WINDOWS__)
 | 
					
						
							|  |  |  |     return GetCurrentThreadId(); | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2015-10-05 10:30:17 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-19 01:30:13 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  | void  | 
					
						
							|  |  |  | Yap_InitFirstWorkerThreadHandle(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   CACHE_REGS | 
					
						
							|  |  |  |   LOCAL_ThreadHandle.id = 0; | 
					
						
							|  |  |  |   LOCAL_ThreadHandle.in_use = TRUE; | 
					
						
							|  |  |  |   LOCAL_ThreadHandle.default_yaam_regs =  | 
					
						
							|  |  |  |     &Yap_standard_regs; | 
					
						
							|  |  |  |   LOCAL_ThreadHandle.current_yaam_regs =  | 
					
						
							|  |  |  |     &Yap_standard_regs; | 
					
						
							|  |  |  |   LOCAL_ThreadHandle.pthread_handle = pthread_self(); | 
					
						
							|  |  |  |   pthread_mutex_init(&REMOTE_ThreadHandle(0).tlock, NULL); | 
					
						
							|  |  |  |   pthread_mutex_init(&REMOTE_ThreadHandle(0).tlock_status, NULL); | 
					
						
							|  |  |  |   LOCAL_ThreadHandle.tdetach = MkAtomTerm(AtomFalse); | 
					
						
							|  |  |  |   LOCAL_ThreadHandle.ref_count = 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Yap_InitThreadPreds(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Yap_InitCPred("$no_threads", 0, p_no_threads, 0); | 
					
						
							|  |  |  |   Yap_InitCPred("$max_workers", 1, p_max_workers, 0); | 
					
						
							|  |  |  |   Yap_InitCPred("$max_threads", 1, p_max_threads, 0); | 
					
						
							|  |  |  |   Yap_InitCPred("$thread_new_tid", 1, p_thread_new_tid, 0); | 
					
						
							|  |  |  |   Yap_InitCPred("$create_thread", 7, p_create_thread, 0); | 
					
						
							|  |  |  |   Yap_InitCPred("$thread_self", 1, p_thread_self, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$thread_status_lock", 1, p_thread_status_lock, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$thread_status_unlock", 1, p_thread_status_unlock, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$thread_zombie_self", 1, p_thread_zombie_self, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$thread_join", 1, p_thread_join, 0); | 
					
						
							|  |  |  |   Yap_InitCPred("$thread_destroy", 1, p_thread_destroy, 0); | 
					
						
							|  |  |  |   Yap_InitCPred("thread_yield", 0, p_thread_yield, 0); | 
					
						
							|  |  |  |   /** @pred thread_yield 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Voluntarily relinquish the processor. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   */ | 
					
						
							|  |  |  |   Yap_InitCPred("$detach_thread", 1, p_thread_detach, 0); | 
					
						
							|  |  |  |   Yap_InitCPred("$thread_detached", 1, p_thread_detached, 0); | 
					
						
							|  |  |  |   Yap_InitCPred("$thread_detached", 2, p_thread_detached2, 0); | 
					
						
							|  |  |  |   Yap_InitCPred("$thread_exit", 0, p_thread_exit, 0); | 
					
						
							|  |  |  |   Yap_InitCPred("thread_setconcurrency", 2, p_thread_set_concurrency, 0); | 
					
						
							|  |  |  |   /** @pred thread_setconcurrency(+ _Old_, - _New_) 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Determine the concurrency of the process, which is defined as the | 
					
						
							|  |  |  |       maximum number of concurrently active threads. `Active` here means | 
					
						
							|  |  |  |       they are using CPU time. This option is provided if the | 
					
						
							|  |  |  |       thread-implementation provides | 
					
						
							|  |  |  |       `pthread_setconcurrency()`. Solaris is a typical example of this | 
					
						
							|  |  |  |       family. On other systems this predicate unifies  _Old_ to 0 (zero) | 
					
						
							|  |  |  |       and succeeds silently. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   */ | 
					
						
							|  |  |  |   Yap_InitCPred("$valid_thread", 1, p_valid_thread, 0); | 
					
						
							| 
									
										
										
										
											2014-11-26 09:45:39 +00:00
										 |  |  |   Yap_InitCPred("mutex_create", 1, p_new_mutex, SafePredFlag); | 
					
						
							| 
									
										
										
										
											2014-11-27 10:02:04 +00:00
										 |  |  |   Yap_InitCPred("mutex_destroy", 1, p_destroy_mutex, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("mutex_lock", 1, p_lock_mutex, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("mutex_trylock", 1, p_trylock_mutex, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("mutex_unlock", 1, p_unlock_mutex, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("with_mutex", 2, p_with_mutex, MetaPredFlag); | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |   Yap_InitCPred("$with_with_mutex", 1, p_with_with_mutex, 0); | 
					
						
							|  |  |  |   Yap_InitCPred("$unlock_with_mutex", 1, p_unlock_with_mutex, 0); | 
					
						
							|  |  |  |   Yap_InitCPred("$mutex_info", 3, p_mutex_info, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$cond_create", 1, p_cond_create, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$cond_destroy", 1, p_cond_destroy, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$cond_signal", 1, p_cond_signal, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$cond_broadcast", 1, p_cond_broadcast, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$cond_wait", 2, p_cond_wait, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$message_queue_create", 1, p_mbox_create, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$message_queue_destroy", 1, p_mbox_destroy, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$message_queue_send", 2, p_mbox_send, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$message_queue_receive", 2, p_mbox_receive, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$message_queue_size", 2, p_mbox_size, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$message_queue_peek", 2, p_mbox_peek, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$thread_stacks", 4, p_thread_stacks, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$signal_thread", 1, p_thread_signal, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$nof_threads", 1, p_nof_threads, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$nof_threads_created", 1, p_nof_threads_created, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$thread_sleep", 4, p_thread_sleep, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$thread_runtime", 1, p_thread_runtime, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$thread_self_lock", 1, p_thread_self_lock, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$thread_run_at_exit", 2, p_thread_atexit, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$thread_unlock", 1, p_thread_unlock, SafePredFlag); | 
					
						
							|  |  |  | #if DEBUG_LOCKS||DEBUG_PE_LOCKS
 | 
					
						
							|  |  |  |   Yap_InitCPred("debug_locks", 0, p_debug_locks, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("nodebug_locks", 0, p_nodebug_locks, SafePredFlag); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | Yap_NOfThreads(void) { | 
					
						
							|  |  |  |   // GLOBAL_ThreadHandlesLock is held
 | 
					
						
							|  |  |  | #ifdef YAPOR
 | 
					
						
							|  |  |  |   return 2; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   return 1; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							|  |  |  | p_no_threads(void) | 
					
						
							|  |  |  | {				/* '$thread_signal'(+P)	 */ | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							|  |  |  | p_nof_threads(void) | 
					
						
							|  |  |  | {				/* '$nof_threads'(+P)	 */ | 
					
						
							|  |  |  |   return Yap_unify(ARG1,MkIntTerm(1)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							|  |  |  | p_max_threads(void) | 
					
						
							|  |  |  | {				/* '$nof_threads'(+P)	 */ | 
					
						
							|  |  |  |   return Yap_unify(ARG1,MkIntTerm(1)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							|  |  |  | p_nof_threads_created(void) | 
					
						
							|  |  |  | {				/* '$nof_threads'(+P)	 */ | 
					
						
							|  |  |  |   return Yap_unify(ARG1,MkIntTerm(1)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							|  |  |  | p_thread_runtime(void) | 
					
						
							|  |  |  | {				/* '$thread_runtime'(+P)	 */ | 
					
						
							|  |  |  |   return Yap_unify(ARG1,MkIntTerm(0)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							|  |  |  | p_thread_self(void) | 
					
						
							|  |  |  | {				/* '$thread_runtime'(+P)	 */ | 
					
						
							|  |  |  |   return Yap_unify(ARG1,MkIntTerm(0)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int | 
					
						
							|  |  |  | p_thread_stacks(void) | 
					
						
							|  |  |  | {				/* '$thread_runtime'(+P)	 */ | 
					
						
							|  |  |  |   return FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							|  |  |  | p_thread_unlock(void) | 
					
						
							|  |  |  | {				/* '$thread_runtime'(+P)	 */ | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							|  |  |  | p_max_workers(void) | 
					
						
							|  |  |  | {				/* '$max_workers'(+P)	 */ | 
					
						
							|  |  |  |   return Yap_unify(ARG1,MkIntTerm(1)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int  | 
					
						
							|  |  |  | p_new_mutex(void) | 
					
						
							| 
									
										
										
										
											2008-06-03 09:24:28 +00:00
										 |  |  | {				/* '$max_workers'(+P)	 */ | 
					
						
							| 
									
										
										
										
											2014-11-09 17:26:08 +00:00
										 |  |  |   static int mutexes = 1; | 
					
						
							|  |  |  |   return Yap_unify(ARG1, MkIntegerTerm(mutexes++) ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  static Int | 
					
						
							|  |  |  |  p_with_mutex( USES_REGS1 ) | 
					
						
							|  |  |  |  { | 
					
						
							|  |  |  |    Int mut; | 
					
						
							|  |  |  |    Term t1 = Deref(ARG1), excep; | 
					
						
							|  |  |  |    Int rc = FALSE; | 
					
						
							|  |  |  |    Int creeping = Yap_get_signal(YAP_CREEP_SIGNAL); | 
					
						
							|  |  |  |    PredEntry *pe; | 
					
						
							|  |  |  |    Term tm = CurrentModule; | 
					
						
							|  |  |  |    Term tg = Deref(ARG2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    if (IsVarTerm(t1)) { | 
					
						
							|  |  |  |        p_new_mutex( PASS_REGS1 ); | 
					
						
							|  |  |  |    } | 
					
						
							| 
									
										
										
										
											2014-11-10 01:55:59 +00:00
										 |  |  |    t1 = Deref(ARG1); | 
					
						
							|  |  |  |    mut = IntOfTerm(t1); | 
					
						
							| 
									
										
										
										
											2014-11-09 17:26:08 +00:00
										 |  |  |    tg = Yap_StripModule(tg, &tm); | 
					
						
							|  |  |  |    if (IsVarTerm(tg)) { | 
					
						
							|  |  |  |       Yap_Error(INSTANTIATION_ERROR, ARG2, "with_mutex/2"); | 
					
						
							|  |  |  |       goto end; | 
					
						
							|  |  |  |    } else if (IsApplTerm(tg)) { | 
					
						
							|  |  |  |      register Functor f = FunctorOfTerm(tg); | 
					
						
							|  |  |  |      register CELL *pt; | 
					
						
							|  |  |  |      size_t i, arity; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     f = FunctorOfTerm(tg); | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |     if (IsExtensionFunctor(f)) { | 
					
						
							|  |  |  |       Yap_Error(TYPE_ERROR_CALLABLE, tg, "with_mutex/2"); | 
					
						
							|  |  |  |       goto end; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     arity = ArityOfFunctor(f); | 
					
						
							|  |  |  |     if (arity > MaxTemps) { | 
					
						
							|  |  |  |       Yap_Error(TYPE_ERROR_CALLABLE, tg, "with_mutex/2"); | 
					
						
							|  |  |  |       goto end; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     pe = RepPredProp(PredPropByFunc(f, tm)); | 
					
						
							|  |  |  |     pt = RepAppl(tg)+1; | 
					
						
							|  |  |  |     for (i= 0; i < arity; i++ ) | 
					
						
							|  |  |  |       XREGS[i+1] = pt[i]; | 
					
						
							|  |  |  |   } else if (IsAtomTerm(tg)) { | 
					
						
							|  |  |  |     pe = RepPredProp(PredPropByAtom(AtomOfTerm(tg), tm)); | 
					
						
							|  |  |  |   } else if (IsPairTerm(tg)) { | 
					
						
							|  |  |  |     register CELL *pt; | 
					
						
							|  |  |  |     Functor f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     f = FunctorDot; | 
					
						
							|  |  |  |     pe = RepPredProp(PredPropByFunc(f, tm)); | 
					
						
							|  |  |  |     pt = RepPair(tg); | 
					
						
							|  |  |  |     XREGS[1] = pt[0]; | 
					
						
							|  |  |  |     XREGS[2] = pt[1]; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     Yap_Error(TYPE_ERROR_CALLABLE, tg, "with_mutex/2"); | 
					
						
							|  |  |  |     goto end; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if ( | 
					
						
							|  |  |  |       pe->OpcodeOfPred != FAIL_OPCODE && | 
					
						
							| 
									
										
										
										
											2015-06-19 01:30:13 +01:00
										 |  |  |       Yap_execute_pred(pe, NULL, false PASS_REGS) ) { | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |     rc = TRUE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |  end: | 
					
						
							|  |  |  |   ARG1 = MkIntegerTerm(mut); | 
					
						
							|  |  |  |   excep = Yap_GetException(); | 
					
						
							|  |  |  |   if (creeping) { | 
					
						
							|  |  |  |     Yap_signal( YAP_CREEP_SIGNAL ); | 
					
						
							|  |  |  |   } else if ( excep != 0) { | 
					
						
							|  |  |  |     return Yap_JumpToEnv(excep); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return rc; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-06-03 09:24:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-13 10:38:20 +00:00
										 |  |  | void  | 
					
						
							|  |  |  | Yap_InitFirstWorkerThreadHandle(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-11 01:20:56 +00:00
										 |  |  | void Yap_InitThreadPreds(void) | 
					
						
							| 
									
										
										
										
											2014-11-09 17:26:08 +00:00
										 |  |  | {  | 
					
						
							| 
									
										
										
										
											2014-12-14 11:55:39 +00:00
										 |  |  |   Yap_InitCPred("with_mutex", 2, p_with_mutex, MetaPredFlag); | 
					
						
							| 
									
										
										
										
											2014-11-26 09:45:39 +00:00
										 |  |  |   Yap_InitCPred("mutex_create", 1, p_new_mutex, SafePredFlag); | 
					
						
							| 
									
										
										
										
											2012-10-19 18:10:48 +01:00
										 |  |  |   Yap_InitCPred("$max_workers", 1, p_max_workers, 0); | 
					
						
							|  |  |  |   Yap_InitCPred("$thread_self", 1, p_thread_self, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$no_threads", 0, p_no_threads, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$max_threads", 1, p_max_threads, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$nof_threads", 1, p_nof_threads, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$nof_threads_created", 1, p_nof_threads_created, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$thread_stacks", 4, p_thread_stacks, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$thread_runtime", 1, p_thread_runtime, SafePredFlag); | 
					
						
							| 
									
										
										
										
											2008-04-08 15:36:53 +00:00
										 |  |  |   Yap_InitCPred("$thread_unlock", 1, p_thread_unlock, SafePredFlag); | 
					
						
							| 
									
										
										
										
											2014-10-19 01:54:57 +01:00
										 |  |  | #if DEBUG_LOCKS||DEBUG_PE_LOCKS
 | 
					
						
							| 
									
										
										
										
											2013-11-12 08:34:26 +00:00
										 |  |  |   Yap_InitCPred("debug_locks", 0, p_debug_locks, SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("nodebug_locks", 0, p_nodebug_locks, SafePredFlag); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-01-23 02:23:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /* THREADS */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2014-11-25 16:41:53 +00:00
										 |  |  |    @} | 
					
						
							| 
									
										
										
										
											2014-09-11 14:06:57 -05:00
										 |  |  | */ |