include thread_sleep functionality.

git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@1653 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
This commit is contained in:
vsc 2006-05-25 16:28:28 +00:00
parent 3b033eee50
commit f5b9000018
10 changed files with 222 additions and 21 deletions

View File

@ -1765,7 +1765,7 @@ p_getcwd(void)
#if HAVE_STRERROR
Yap_Error(OPERATING_SYSTEM_ERROR, ARG1, "%s in getcwd/1", strerror(errno));
#else
Yap_Error(OPERATING_SYSTEM_ERROR, ARG1, "in getcwd/1");
Yap_Error(OPERATING_SYSTEM_ERROR, ARG1, "error %d in getcwd/1", errno);
#endif
return FALSE;
}

View File

@ -193,6 +193,56 @@ p_create_thread(void)
return FALSE;
}
static Int
p_thread_sleep(void)
{
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;
if (!nanosleep(&req, &oreq)) {
#if HAVE_STRERROR
Yap_Error(OPERATING_SYSTEM_ERROR, ARG1, "%s in thread_sleep/2", strerror(errno));
#else
Yap_Error(OPERATING_SYSTEM_ERROR, ARG1, "error %d in thread_sleep/2", errno);
#endif
return FALSE;
}
return Yap_unify(ARG3,MkIntegerTerm(oreq.tv_sec)) &&
Yap_unify(ARG4,MkIntegerTerm(oreq.tv_nsec));
#elif HAVE_NANOSLEEP
UInt ntime = IntegerOfTerm(Deref(ARG2));
struct timespec req, oreq ;
req.tv_sec = time;
req.tv_nsec = ntime;
if (!nanosleep(&req, &oreq)) {
#if HAVE_STRERROR
Yap_Error(OPERATING_SYSTEM_ERROR, ARG1, "%s in thread_sleep/2", strerror(errno));
#else
Yap_Error(OPERATING_SYSTEM_ERROR, ARG1, "error %d in thread_sleep/2", errno);
#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
Yap_Error(OPERATING_SYSTEM_ERROR, ARG1, "%s in thread_sleep/2", strerror(errno));
#else
Yap_Error(OPERATING_SYSTEM_ERROR, ARG1, "error %d in thread_sleep/2", errno);
#endif
}
return Yap_unify(ARG3,MkIntegerTerm(rtime)) &&
Yap_unify(ARG4,MkIntTerm(0L));
#else
Yap_Error(OPERATING_SYSTEM_ERROR, ARG1, "no support for thread_sleep in this YAP configuration");
#endif
}
static Int
p_thread_self(void)
{
@ -573,6 +623,7 @@ void Yap_InitThreadPreds(void)
Yap_InitCPred("$signal_thread", 1, p_thread_signal, SafePredFlag|HiddenPredFlag);
Yap_InitCPred("$nof_threads", 1, p_nof_threads, SafePredFlag|HiddenPredFlag);
Yap_InitCPred("$nof_threads_created", 1, p_nof_threads_created, SafePredFlag|HiddenPredFlag);
Yap_InitCPred("$thread_sleep", 2, p_thread_sleep, SafePredFlag|HiddenPredFlag);
Yap_InitCPred("$thread_runtime", 1, p_thread_runtime, SafePredFlag|HiddenPredFlag);
}

View File

@ -16,6 +16,8 @@
<h2>Yap-5.1.2:</h2>
<ul>
<li> FIXED: check_callable should check for modules (obs Paulo Moura).</li>
<li> NEW: add thread_sleep/1, mostly works like system:sleep/1 (request from Paulo Moura).</li>
<li> NEW: add select/3 and intersection/3 to SWI emulation.</li>
<li> FIXED: always keep in mind that Yap_WakeUp may change H (would
break chr).</li>

View File

@ -178,6 +178,7 @@
#undef HAVE_MKTEMP
#undef HAVE_MKTIME
#undef HAVE_MMAP
#undef HAVE_NANOSLEEP
#undef HAVE_NSLINKMODULE
#undef HAVE_OPENDIR
#undef HAVE_POPEN

103
configure vendored
View File

@ -13783,9 +13783,110 @@ done
for ac_func in memcpy memmove mkstemp mktemp
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5
echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
if eval "test \"\${$as_ac_var+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
For example, HP-UX 11i <limits.h> declares gettimeofday. */
#define $ac_func innocuous_$ac_func
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func (); below.
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
<limits.h> exists even on freestanding compilers. */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
#undef $ac_func
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
{
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char $ac_func ();
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
choke me
#else
char (*f) () = $ac_func;
#endif
#ifdef __cplusplus
}
#endif
int
main ()
{
return f != $ac_func;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
eval "$as_ac_var=yes"
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
eval "$as_ac_var=no"
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
if test `eval echo '${'$as_ac_var'}'` = yes; then
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
fi
done
for ac_func in memcpy memmove mkstemp mktemp mktime opendir
for ac_func in nanosleep mktime opendir
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5

View File

@ -1137,7 +1137,8 @@ AC_CHECK_FUNCS(gethostbyname gethostid gethostname)
AC_CHECK_FUNCS(gethrtime getpwnam getrusage gettimeofday getwd)
AC_CHECK_FUNCS(isatty isnan kill labs link lgamma)
AC_CHECK_FUNCS(localtime lstat mallinfo)
AC_CHECK_FUNCS(memcpy memmove mkstemp mktemp mktime opendir)
AC_CHECK_FUNCS(memcpy memmove mkstemp mktemp)
AC_CHECK_FUNCS(nanosleep mktime opendir)
AC_CHECK_FUNCS(putenv rand random readlink regexec)
AC_CHECK_FUNCS(rename rint rl_set_prompt sbrk select)
AC_CHECK_FUNCS(setbuf setlinebuf sigaction siggetmask siginterrupt)

View File

@ -10071,6 +10071,14 @@ 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.
@item thread_sleep(+@var{Time}})
@findex thread_sleep/1
@snindex thread_sleep/1
@cnindex thread_sleep/1
Make current thread sleep for @var{Time} seconds. @var{Time} may be an
integer or a floating point number. This call should not be used if
alarms are also being used.
@end table

View File

@ -8,8 +8,11 @@
* *
**************************************************************************
* *
* $Id: sys.c,v 1.27 2006-05-17 18:38:11 vsc Exp $ *
* $Id: sys.c,v 1.28 2006-05-25 16:28:28 vsc Exp $ *
* mods: $Log: not supported by cvs2svn $
* mods: Revision 1.27 2006/05/17 18:38:11 vsc
* mods: make system library use true file name
* mods:
* mods: Revision 1.26 2006/04/25 03:23:40 vsc
* mods: fix ! in debugger (execute_clause)
* mods: improve system/1 and execute/1
@ -842,7 +845,7 @@ static int
p_sleep(void)
{
YAP_Term ts = YAP_ARG1;
long int secs = 0, usecs = 0, out;
unsigned long int secs = 0, usecs = 0, out;
if (YAP_IsIntTerm(ts)) {
secs = YAP_IntOfTerm(ts);
} else if (YAP_IsFloatTerm(ts)) {
@ -850,25 +853,39 @@ p_sleep(void)
if (tfl > 1.0)
secs = tfl;
else
usecs = tfl*1000;
usecs = tfl*1000000;
}
#if defined(__MINGW32__) || _MSC_VER
if (secs) usecs = secs*1000;
if (secs) usecs = secs*1000 + usecs/1000;
Sleep(usecs);
/* no errors possible */
out = 0;
#else
#if HAVE_USLEEP
#elif HAVE_NANOSLEEP
{
struct timespec req;
if (YAP_IsFloatTerm(ts)) {
double tfl = YAP_FloatOfTerm(ts);
req.tv_nsec = (tfl-floor(tfl))*1000000000;
req.tv_sec = rint(tfl);
} else {
req.tv_nsec = 0;
req.tv_sec = secs;
}
out = nanosleep(&req, NULL);
}
#elif HAVE_USLEEP
if (usecs > 0) {
usleep(usecs);
out = 0;
out = usleep(usecs);
} else
#endif
#if HAVE_SLEEP
#elif HAVE_SLEEP
{
out = sleep(secs);
}
#else
YAP_Error(0,0L,"sleep not available in this configuration");
return FALSE:
#endif
#endif /* defined(__MINGW32__) || _MSC_VER */
return(YAP_Unify(YAP_ARG2, YAP_MkIntTerm(out)));
}

View File

@ -774,14 +774,15 @@ not(G) :- \+ '$execute'(G).
).
'$check_callable'(V,G) :- var(V), !,
'$current_module'(Mod),
'$do_error'(instantiation_error,Mod:G).
'$do_error'(instantiation_error,G).
'$check_callable'(M:G1,G) :- var(M), !,
'$do_error'(instantiation_error,G).
'$check_callable'(_:G1,G) :- !,
'$check_callable'(G1,G).
'$check_callable'(A,G) :- number(A), !,
'$current_module'(Mod),
'$do_error'(type_error(callable,A),Mod:G).
'$do_error'(type_error(callable,A),G).
'$check_callable'(R,G) :- db_reference(R), !,
'$current_module'(Mod),
'$do_error'(type_error(callable,R),Mod:G).
'$do_error'(type_error(callable,R),G).
'$check_callable'(_,_).
% Called by the abstract machine, if no clauses exist for a predicate

View File

@ -476,13 +476,32 @@ thread_local(X) :-
'$do_error'(type_error(callable,X),thread_local(Mod:X)).
thread_sleep(Time) :-
var(Time), !,
'$do_error'(instantiation_error,thread_sleep(Time)).
thread_sleep(Time) :-
integer(Time), Time >= 0, !,
'$thread_sleep'(Time,0,_,_).
thread_sleep(Time) :-
float(Time), Time >= 0, !,
STime is integer(float_integer_part(Time)),
NTime is integer(float_fractional_part(Time))*1000000000,
'$thread_sleep'(STime,NTime,_,_).
thread_sleep(Time) :-
number(Time),
'$do_error'(domain_error(not_less_than_zero,Time),thread_sleep(Time)).
thread_sleep(Time) :-
'$do_error'(type_error(number,Time),thread_sleep(Time)).
thread_signal(Thread, Goal) :-
var(Thread), !,
'$do_error'(instantiation_error,thread_signal(Thread, Goal)).
thread_signal(Thread, Goal) :-
'$check_callable'(Goal,thread_signal(Thread,Goal)).
thread_signal(Thread, Goal) :-
recorded('$thread_alias',[Id|Thread],_),
recorded('$thread_alias',[Id|Thread],_), !,
'$thread_signal'(Id, Goal).
thread_signal(Thread, Goal) :-
integer(Thread), !,