diff --git a/C/absmi.c b/C/absmi.c index 69eff2e09..72993da2b 100644 --- a/C/absmi.c +++ b/C/absmi.c @@ -9311,11 +9311,11 @@ Yap_absmi(int inp) CmpPredicate f = PREG->u.llxx.p->cs.d_code; saveregs(); d0 = (CELL) (f) (d0,d1); - + setregs(); } - setregs(); if (!d0) { - PREG = PREG->u.llxx.f; + if (PREG != FAILCODE) + PREG = PREG->u.llxx.f; JMPNext(); } PREG = NEXTOP(PREG, llxx); @@ -9383,10 +9383,11 @@ Yap_absmi(int inp) CmpPredicate f = PREG->u.llxy.p->cs.d_code; saveregs(); d0 = (CELL) (f) (d0,d1); + setregs(); } - setregs(); if (!d0) { - PREG = PREG->u.llxy.f; + if (PREG != FAILCODE) + PREG = PREG->u.llxy.f; JMPNext(); } PREG = NEXTOP(PREG, llxy); @@ -9454,10 +9455,11 @@ Yap_absmi(int inp) CmpPredicate f = PREG->u.llxy.p->cs.d_code; saveregs(); d0 = (CELL) (f) (d0,d1); + setregs(); } - setregs(); if (!d0) { - PREG = PREG->u.llxy.f; + if (PREG != FAILCODE) + PREG = PREG->u.llxy.f; JMPNext(); } PREG = NEXTOP(PREG, llxy); @@ -9531,7 +9533,8 @@ Yap_absmi(int inp) } setregs(); if (!d0) { - PREG = PREG->u.llyy.f; + if (PREG != FAILCODE) + PREG = PREG->u.llyy.f; JMPNext(); } PREG = NEXTOP(PREG, llyy); diff --git a/C/cdmgr.c b/C/cdmgr.c index b951d2083..d3481898f 100644 --- a/C/cdmgr.c +++ b/C/cdmgr.c @@ -2652,16 +2652,6 @@ code_in_pred(PredEntry *pp, Atom *pat, UInt *parity, yamop *codeptr) { } clcode = pp->cs.p_code.FirstClause; if (clcode != NULL) { - char *code_end; - if (pp->PredFlags & LogUpdatePredFlag) { - LogUpdClause *cl = ClauseCodeToLogUpdClause(pp->cs.p_code.TrueCodeOfPred); - code_end = (char *)cl + cl->ClSize; - } else if (!(pp->PredFlags & DynamicPredFlag)) { - code_end = NULL; - } else { - StaticClause *cl = ClauseCodeToStaticClause(pp->cs.p_code.TrueCodeOfPred); - code_end = (char *)cl + cl->ClSize; - } if (pp->PredFlags & LogUpdatePredFlag) { LogUpdClause *cl = ClauseCodeToLogUpdClause(clcode); do { diff --git a/C/dbase.c b/C/dbase.c index d71ac3b2b..103e7666b 100644 --- a/C/dbase.c +++ b/C/dbase.c @@ -1830,6 +1830,7 @@ record_lu(PredEntry *pe, Term t, int position) cl->ClPred = pe; cl->ClExt = NULL; cl->ClPrev = cl->ClNext = NULL; + cl->ClSize = ((CODEADDR)&(x->Contents)-(CODEADDR)cl)+x->NOfCells*sizeof(CELL); #if defined(YAPOR) || defined(THREADS) INIT_LOCK(cl->ClLock); INIT_CLREF_COUNT(cl); diff --git a/docs/yap.tex b/docs/yap.tex index ca56b557f..85d857dfa 100644 --- a/docs/yap.tex +++ b/docs/yap.tex @@ -12147,7 +12147,7 @@ Subnodes of Threads @end menu -\node Creating and destroying Prolog threads, , ,Threads +@node Creating and destroying Prolog threads, Monitoring Threads, ,Threads @section Creating and destroying Prolog threads @table @code @@ -12163,26 +12163,22 @@ thread-identifier of the created thread is unified to @var{Id}. @var{Options} is a list of options. Currently defined options are: @table @code - @item{stack} -Set the limit in K-Bytes to which the local stack of this thread may grow. If -omited, the limit of the calling thread is used. See also the -\cmdlineoption{-s} commandline option. + @item stack +Set the limit in K-Bytes to which the Prolog stacks of +this thread may grow. If omited, the limit of the calling thread is +used. See also the \cmdlineoption{-s} commandline option. - @item{trail} + @item trail Set the limit in K-Bytes to which the trail stack of this thread may grow. If omited, the limit of the calling thread is used. See also the \cmdlineoption{-t} commandline option. - @item{stack} -Set the limit in K-Bytes to which the system stack of this thread may -grow. The default, mimimum and maximum values are system-dependant. - - @item{alias} + @item alias Associate an alias-name with the thread. This named may be used to refer to the thread and remains valid until the thread is joined (see @code{thread_join/2}). - @item{detached} + @item detached If @code{false} (default), the thread can be waited for using @code{thread_join/2}. @code{thread_join/2} must be called on this thread to reclaim the all resources associated to the thread. If @code{true}, @@ -12221,17 +12217,18 @@ exit-status of the thread is retained until @code{thread_join/2} is called on the thread. Defined values for @var{Status} are: @table @code - @item{true}{} + @item true The goal has been proven successfully. - @item{false}{} + @item false The goal has failed. - @item{exception}{@var{Term}} The thread is terminated on an + @item exception(@var{Term}) + The thread is terminated on an exception. See @code{print_message/2} to turn system exceptions into readable messages. - @item{exited}{@var{Term}} + @item exited(@var{Term) The thread is terminated on thread_exit/1 using the argument @var{Term}. @end table @@ -12262,82 +12259,95 @@ result-state for @code{thread_join/2}. If the thread has the attribute retrieved using @code{thread_join/2} making the value of @var{Term} irrelevant. The Prolog stacks and C-thread are reclaimed. - \predicate{thread_at_exit}{1}{:Goal} -Run @var{Goal} just before releasing the thread resources. This is to be -compared to at_halt/1, but only for the current thread. These hooks are -ran regardless of why the execution of the thread has been completed. As -these hooks are run, the return-code is already available through -current_thread/2 using the result of thread_self/1 as thread-identifier. +@item thread_at_exit(:@var{Term}) +@findex thread_at_exit/1 +@snindex thread_at_exit/1 +@cnindex thread_at_exit/1 +Run @var{Goal} just before releasing the thread resources. This is to +be compared to @code{at_halt/1}, but only for the current +thread. These hooks are ran regardless of why the execution of the +thread has been completed. As these hooks are run, the return-code is +already available through @code{current_thread/2} using the result of +@code{thread_self/1} as thread-identifier. - \predicate{thread_setconcurrency}{2}{-Old, +New} -\index{Solaris}% +@item thread_setconcurrency(+@var{Old}, -@var{New}) +@findex thread_setconcurrency/2 +@snindex thread_setconcurrency/2 +@cnindex thread_setconcurrency/2 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 +maximum number of concurrently active threads. `Active' here means +they are using CPU time. This option is provided if the +thread-implementation provides +@code{pthread_setconcurrency()}. Solaris is a typical example of this family. On other systems this predicate unifies @var{Old} to 0 (zero) and succeeds silently. @end table -\section{Monitoring threads} \label{sec:thmonitor} +@node Monitoring threads, Thread Communication,Creating and destroying Prolog threads,Threads +@section Monitoring threads Normal multi-threaded applications should not need these the predicates from this section because almost any usage of these predicates is unsafe. For example checking the existence of a thread before signalling it is of no use as it may vanish between the two calls. Catching -exceptions using catch/3 is the only safe way to deal with +exceptions using @code{catch/3} is the only safe way to deal with thread-existence errors. -These predicates are provided for diagnosis and monitoring tasks. See -also \secref{thutil}, describing more high-level primitives. +These predicates are provided for diagnosis and monitoring tasks. @table @code +@item current_thread(+@var{Id}, -@var{Status}) +@findex current_thread/2 +@snindex current_thread/2 +@cnindex current_thread/2 \predicate{current_thread}{2}{?Id, ?Status} Enumerates identifiers and status of all currently known threads. Calling current_thread/2 does not influence any thread. See also -thread_join/2. For threads that have an alias-name, this name is +@code{thread_join/2}. For threads that have an alias-name, this name is returned in @var{Id} instead of the numerical thread identifier. @var{Status} is one of: @table @code - @item{running}{} + @item running The thread is running. This is the initial status of a thread. Please note that threads waiting for something are considered running too. - @item{false}{} + @item false The @var{Goal} of the thread has been completed and failed. - @item{true}{} + @item true The @var{Goal} of the thread has been completed and succeeded. - @item{exited}{Term} -The @var{Goal} of the thread has been terminated using thread_exit/1 + @item exited(@var{Term}) +The @var{Goal} of the thread has been terminated using @code{thread_exit/1} with @var{Term} as argument. If the underlying native thread has exited (using pthread_exit()) @var{Term} is unbound. - @item{exception}{Term} + @item exception(@var{Term}) The @var{Goal} of the thread has been terminated due to an uncaught -exception (see throw/1 and catch/3). +exception (see @code{throw/1} and @code{catch/3}). @end table - \predicate{thread_statistics}{3}{+Id, +Key, -Value} -Obtains statistical information on thread @var{Id} as statistics/2 +@item thread_statistics(+@var{Id}, +@var{Key}, -@var{Value}) +@findex thread_statistics/3 +@snindex thread_statistics/3 +@cnindex thread_statistics/3 +Obtains statistical information on thread @var{Id} as @code{statistics/2} does in single-threaded applications. This call returns all keys -of statistics/2, although only information statistics about the -stacks and CPU time yield different values for each thread.% - \footnote{Getting the CPU-time of a different thread is - not supported on all platforms. For Microsoft, - it does not work in 95/98/ME. For POSIX systems - it requires times() to return values specific for - the calling thread.} +of @code{statistics/2}, although only information statistics about the +stacks and CPU time yield different values for each thread. +@item mutex_statistics +@findex mutex_statistics/0 +@snindex mutex_statistics/0 +@cnindex mutex_statistics/0 \predicate{mutex_statistics}{0}{} Print usage statistics on internal mutexes and mutexes associated with dynamic predicates. For each mutex two numbers are printed: the number of times the mutex was acquired and the number of -\jargon{collisions}: the number times the calling thread has to +collisions: the number times the calling thread has to wait for the mutex. The collistion-count is not available on Windows as this would break portability to Windows-95/98/ME or significantly harm performance. Generally collision count is @@ -12345,7 +12355,8 @@ close to zero on single-CPU hardware. @end table -\section{Thread communication} \label{sec:threadcom} +@node Thread Communication, ,Monitoring threads, Threads +@section Thread communication \subsection{Message queues} \label{sec:msgqueue}