rktio: initial import of librktio to racket

This commit is contained in:
Matthew Flatt 2017-06-13 15:16:26 -06:00
parent 636b1637b4
commit 425fe36fa5
16 changed files with 277 additions and 619 deletions

View File

@ -655,6 +655,8 @@ collectsdir
LTA
LTO
LIBRACKET_DEP
LIBRKTIO_FOR_LIB
LIBRKTIO_FOR_DLL
FOREIGNTARGET
FOREIGN_CONVENIENCE
FOREIGN_OBJSLIB
@ -6942,6 +6944,8 @@ if test "${enable_shared}" = "yes" ; then
FOREIGN_OBJSLIB="\$(FOREIGN_LIB)"
MZOPTIONS="$MZOPTIONS -DMZ_USES_SHARED_LIB"
STRIP_LIB_DEBUG=":"
LIBRKTIO_FOR_DLL="\$(LIBRKTIO)"
LIBRKTIO_FOR_LIB=""
else
LIBSFX=a
WXLIBS=WXLIBSNORM
@ -6956,6 +6960,8 @@ else
PLAIN_CC='$(CC)'
FOREIGN_CONVENIENCE=""
FOREIGN_OBJSLIB="\$(FOREIGN_OBJS)"
LIBRKTIO_FOR_LIB="\$(LIBRKTIO)"
LIBRKTIO_FOR_DLL=""
fi
############## final output ################
@ -7083,6 +7089,9 @@ LIBS="$LIBS $EXTRALIBS"

View File

@ -86,6 +86,7 @@ normal-bin:
common:
$(MAKE) g-c
$(MAKE) @FOREIGNTARGET@
$(MAKE) rktio
cgc:
$(MAKE) cgc-core
@ -151,6 +152,9 @@ foreign-stuff:
foreign-stub:
cd $(FOREIGN_DIR); $(MAKE) stub
rktio:
cd ../rktio; $(MAKE)
mzlibrary:
cd src; $(MAKE) all
$(MAKE) libracket.@LIBSFX@
@ -179,8 +183,10 @@ FOREIGN_USED_OBJSLIB = $(FOREIGN_OBJSLIB)
FOREIGN_NOT_USED_LIB = $(FOREIGN_OBJ)
FOREIGN_NOT_USED_OBJSLIB = $(FOREIGN_OBJ)
libracket.@LIBSFX@: src/*.@LTO@ $(@FOREIGN_IF_USED@_LIB)
$(NICEAR) $(AR) $(ARFLAGS) libracket.@LIBSFX@ src/*.@LTO@ $(@FOREIGN_IF_USED@_OBJSLIB) @LIBRACKET_DEP@
LIBRKTIO = ../rktio/librktio.@LTA@
libracket.@LIBSFX@: src/*.@LTO@ $(@FOREIGN_IF_USED@_LIB) @LIBRKTIO_FOR_DLL@
$(NICEAR) $(AR) $(ARFLAGS) libracket.@LIBSFX@ src/*.@LTO@ $(@FOREIGN_IF_USED@_OBJSLIB) @LIBRKTIO_FOR_DLL@ @LIBRACKET_DEP@
$(RANLIB) libracket.@LIBSFX@
# Irix sproc, only
@ -189,8 +195,8 @@ sproc.@LTO@: @GCDIR@/sproc.@LTO@
# Unix ----------------------------------------
racket@CGC@@NOT_OSX@@NOT_MINGW@: libracket.@LIBSFX@ libmzgc.@LIBSFX@ main.@LTO@ $(SPECIALIZINGOBJECTS)
@MZLINKER@ -o racket@CGC@ main.@LTO@ $(SPECIALIZINGOBJECTS) libracket.@LIBSFX@ libmzgc.@LIBSFX@ @LDFLAGS@ @LIBS@
racket@CGC@@NOT_OSX@@NOT_MINGW@: libracket.@LIBSFX@ libmzgc.@LIBSFX@ main.@LTO@ @LIBRKTIO_FOR_LIB@ $(SPECIALIZINGOBJECTS)
@MZLINKER@ -o racket@CGC@ main.@LTO@ $(SPECIALIZINGOBJECTS) libracket.@LIBSFX@ libmzgc.@LIBSFX@ @LIBRKTIO_FOR_LIB@ @LDFLAGS@ @LIBS@
mzcom@CGC@@NOT_MINGW@:
$(NOOP)
@ -199,9 +205,9 @@ mzcom@CGC@@NOT_MINGW@:
MZFW = Racket.framework/Versions/$(FWVERSION)/Racket
$(MZFW): libracket.@LIBSFX@ libmzgc.@LIBSFX@ $(SPECIALIZINGOBJECTS)
$(MZFW): libracket.@LIBSFX@ libmzgc.@LIBSFX@ $(SPECIALIZINGOBJECTS) $(LIBRKTIO)
mkdir -p Racket.framework/Versions/$(FWVERSION)
@MZLINKER@ -o $(MZFW) @LDFLAGS@ -framework CoreFoundation -dynamiclib -all_load $(SPECIALIZINGOBJECTS) libracket.@LIBSFX@ libmzgc.@LIBSFX@ @LIBS@
@MZLINKER@ -o $(MZFW) @LDFLAGS@ -framework CoreFoundation -dynamiclib -all_load $(SPECIALIZINGOBJECTS) libracket.@LIBSFX@ libmzgc.@LIBSFX@ $(LIBRKTIO) @LIBS@
rm -f Racket.framework/Racket
ln -s Versions/$(FWVERSION)/Racket Racket.framework/Racket
@ -218,9 +224,9 @@ lib/libmzgcxxxxxxx.dll: libmzgc.@LIBSFX@
mzsj86g.o: $(srcdir)/src/mzsj86g.S
$(CC) -c -o mzsj86g.o $(srcdir)/src/mzsj86g.S
lib/libracketxxxxxxx.dll: lib/libmzgcxxxxxxx.dll libracket.@LIBSFX@ mzsj86g.o
lib/libracketxxxxxxx.dll: lib/libmzgcxxxxxxx.dll libracket.@LIBSFX@ mzsj86g.o $(LIBRKTIO)
mkdir -p lib
@MZLINKER@ -shared -o lib/libracketxxxxxxx.dll mzsj86g.o -Wl,--output-def -Wl,libracket.def -Wl,--whole-archive libracket.@LIBSFX@ -Wl,--no-whole-archive @LDFLAGS@ -lshell32 -luser32 -lws2_32 lib/libmzgcxxxxxxx.dll -static-libgcc @LIBS@
@MZLINKER@ -shared -o lib/libracketxxxxxxx.dll mzsj86g.o -Wl,--output-def -Wl,libracket.def -Wl,--whole-archive libracket.@LIBSFX@ -Wl,--no-whole-archive $(LIBRKTIO) @LDFLAGS@ -lshell32 -luser32 -lws2_32 lib/libmzgcxxxxxxx.dll -static-libgcc @LIBS@
libracket.dll.a: lib/libracketxxxxxxx.dll
@DLLTOOL@ --def libracket.def -D libracketxxxxxxx.dll --output-exp libracketxxxxxxx.exp --output-lib libracketxxxxxxx.lib --output-delaylib libracket.dll.a

View File

@ -1760,6 +1760,8 @@ if test "${enable_shared}" = "yes" ; then
FOREIGN_OBJSLIB="\$(FOREIGN_LIB)"
MZOPTIONS="$MZOPTIONS -DMZ_USES_SHARED_LIB"
STRIP_LIB_DEBUG=":"
LIBRKTIO_FOR_DLL="\$(LIBRKTIO)"
LIBRKTIO_FOR_LIB=""
else
LIBSFX=a
WXLIBS=WXLIBSNORM
@ -1774,6 +1776,8 @@ else
PLAIN_CC='$(CC)'
FOREIGN_CONVENIENCE=""
FOREIGN_OBJSLIB="\$(FOREIGN_OBJS)"
LIBRKTIO_FOR_LIB="\$(LIBRKTIO)"
LIBRKTIO_FOR_DLL=""
fi
############## final output ################
@ -1865,6 +1869,9 @@ AC_SUBST(FOREIGN_OBJSLIB)
AC_SUBST(FOREIGN_CONVENIENCE)
AC_SUBST(FOREIGNTARGET)
AC_SUBST(LIBRKTIO_FOR_DLL)
AC_SUBST(LIBRKTIO_FOR_LIB)
AC_SUBST(LIBRACKET_DEP)
AC_SUBST(LTO)

View File

@ -25,7 +25,8 @@ RANLIB = @RANLIB@
CFLAGS = @CFLAGS@ @COMPFLAGS@ @PROFFLAGS@
CPPFLAGS = @PREFLAGS@
ALL_CPPFLAGS = -I$(builddir)/.. -I$(srcdir)/../include $(CPPFLAGS) @OPTIONS@ @GC2OPTIONS@ @MZOPTIONS@
RKTIO_INC = -I$(srcdir)/../../rktio -I../../rktio
ALL_CPPFLAGS = -I$(builddir)/.. -I$(srcdir)/../include $(RKTIO_INC) $(CPPFLAGS) @OPTIONS@ @GC2OPTIONS@ @MZOPTIONS@
ALL_CFLAGS = $(CFLAGS) $(ALL_CPPFLAGS)
LIBS = @LIBS@
@ -498,18 +499,20 @@ FOREIGN_USED_OBJSLIB = $(FOREIGN_OBJSLIB)
FOREIGN_NOT_USED_LIB = $(FOREIGN_OBJ)
FOREIGN_NOT_USED_OBJSLIB =
LIBRKTIO = ../../rktio/librktio.@LTA@
EXTRA_GMP_DEP_FILE = ../src/@EXTRA_GMP_OBJ@
EXTRA_GMP = @EXTRA_GMP_DEP@
EXTRA_OBJS_T = $(EXTRA_GMP) ../src/unwind.@LTO@ $(@FOREIGN_IF_USED@_LIB)
EXTRA_OBJS_L = $(EXTRA_GMP) ../src/unwind.@LTO@ $(@FOREIGN_IF_USED@_OBJSLIB)
EXTRA_OBJS_T = $(EXTRA_GMP) ../src/unwind.@LTO@ $(@FOREIGN_IF_USED@_LIB) @LIBRKTIO_FOR_DLL@
EXTRA_OBJS_L = $(EXTRA_GMP) ../src/unwind.@LTO@ $(@FOREIGN_IF_USED@_OBJSLIB) @LIBRKTIO_FOR_DLL@
../libracket3m.@LIBSFX@: $(OBJS) $(EXTRA_OBJS_T) gc2.@LTO@
$(NICEAR) $(AR) $(ARFLAGS) ../libracket3m.@LIBSFX@ $(OBJS) $(EXTRA_OBJS_L) gc2.@LTO@
../libracket3m.@LIBSFX@: $(OBJS) $(EXTRA_OBJS_T) gc2.@LTO@ @LIBRKTIO_FOR_DLL@
$(NICEAR) $(AR) $(ARFLAGS) ../libracket3m.@LIBSFX@ $(OBJS) $(EXTRA_OBJS_L) gc2.@LTO@ @LIBRKTIO_FOR_DLL@
$(RANLIB) ../libracket3m.@LIBSFX@
../racket@MMM@@NOT_OSX@@NOT_MINGW@: main.@LTO@ ../libracket3m.@LIBSFX@
cd ..; @MZLINKER@ -o racket@MMM@ @PROFFLAGS@ gc2/main.@LTO@ libracket3m.@LIBSFX@ @LDFLAGS@ $(LIBS)
../racket@MMM@@NOT_OSX@@NOT_MINGW@: main.@LTO@ ../libracket3m.@LIBSFX@ @LIBRKTIO_FOR_LIB@
cd ..; @MZLINKER@ -o racket@MMM@ @PROFFLAGS@ gc2/main.@LTO@ libracket3m.@LIBSFX@ @LIBRKTIO_FOR_LIB@ @LDFLAGS@ $(LIBS)
# The above "cd .." prevents a problem with libtool's generated script in --enable-shared mode,
# at least for Mac OS X. Beware of changing LIBS or LDFLAGS to inclucde something with a relative
@ -517,9 +520,9 @@ EXTRA_OBJS_L = $(EXTRA_GMP) ../src/unwind.@LTO@ $(@FOREIGN_IF_USED@_OBJSLIB)
MZFWMMM = Racket.framework/Versions/$(FWVERSION)_3m/Racket
$(MZFWMMM): ../libracket3m.@LIBSFX@
$(MZFWMMM): ../libracket3m.@LIBSFX@ $(LIBRKTIO)
mkdir -p "Racket.framework/Versions/$(FWVERSION)_3m"
@MZLINKER@ -o $(MZFWMMM) -framework CoreFoundation -dynamiclib -all_load ../libracket3m.@LIBSFX@ @LDFLAGS@ $(LIBS)
@MZLINKER@ -o $(MZFWMMM) -framework CoreFoundation -dynamiclib -all_load ../libracket3m.@LIBSFX@ $(LIBRKTIO) @LDFLAGS@ $(LIBS)
rm -f Racket.framework/Racket
ln -s Versions/$(FWVERSION)_3m/Racket Racket.framework/Racket
@ -529,9 +532,9 @@ $(MZFWMMM): ../libracket3m.@LIBSFX@
cp "Racket.framework/Versions/$(FWVERSION)_3m/Racket" "../Racket.framework/Versions/$(FWVERSION)_3m/Racket"
/usr/bin/install_name_tool -change "Racket.framework/Versions/$(FWVERSION)_3m/Racket" "@executable_path/Racket.framework/Versions/$(FWVERSION)_3m/Racket" "../racket@MMM@"
../lib/libracket3mxxxxxxx.dll: ../libracket3m.@LIBSFX@ ../mzsj86g.o
../lib/libracket3mxxxxxxx.dll: ../libracket3m.@LIBSFX@ ../mzsj86g.o $(LIBRKTIO)
mkdir -p ../lib
@MZLINKER@ -shared -o ../lib/libracket3mxxxxxxx.dll ../mzsj86g.o -Wl,--output-def -Wl,libracket3m.def -Wl,--whole-archive ../libracket3m.@LIBSFX@ -Wl,--no-whole-archive @LDFLAGS@ -lshell32 -luser32 -lws2_32 -static-libgcc @LIBS@
@MZLINKER@ -shared -o ../lib/libracket3mxxxxxxx.dll ../mzsj86g.o -Wl,--output-def -Wl,libracket3m.def -Wl,--whole-archive ../libracket3m.@LIBSFX@ -Wl,--no-whole-archive $(LIBRKTIO) @LDFLAGS@ -lshell32 -luser32 -lws2_32 -static-libgcc @LIBS@
libracket3m.dll.a: ../lib/libracket3mxxxxxxx.dll
@DLLTOOL@ --def libracket3m.def -D libracket3mxxxxxxx.dll --output-exp libracket3mxxxxxxx.exp --output-lib libracket3mxxxxxxx.lib --output-delaylib libracket3m.dll.a

View File

@ -144,6 +144,7 @@ typedef struct Thread_Local_Variables {
uintptr_t force_gc_for_place_accounting_;
uintptr_t scheme_os_thread_id_;
int scheme_starting_up_;
struct rktio_t *scheme_rktio_;
void *bignum_cache_[BIGNUM_CACHE_SIZE];
int cache_count_;
struct Scheme_Hash_Table *toplevels_ht_;
@ -550,6 +551,7 @@ XFORM_GC_VARIABLE_STACK_THROUGH_THREAD_LOCAL;
#define force_gc_for_place_accounting XOA (scheme_get_thread_local_variables()->force_gc_for_place_accounting_)
#define scheme_os_thread_id XOA (scheme_get_thread_local_variables()->scheme_os_thread_id_)
#define scheme_starting_up XOA (scheme_get_thread_local_variables()->scheme_starting_up_)
#define scheme_rktio XOA (scheme_get_thread_local_variables()->scheme_rktio_)
#define bignum_cache XOA (scheme_get_thread_local_variables()->bignum_cache_)
#define cache_count XOA (scheme_get_thread_local_variables()->cache_count_)
#define toplevels_ht XOA (scheme_get_thread_local_variables()->toplevels_ht_)

View File

@ -11,7 +11,8 @@ MZSRC = $(srcdir)
CFLAGS = @CFLAGS@ @COMPFLAGS@ @PROFFLAGS@
CPPFLAGS = @PREFLAGS@
ALL_CFLAGS = $(CFLAGS) -I$(builddir)/.. -I$(srcdir)/../include $(CPPFLAGS) @OPTIONS@ @MZOPTIONS@
RKTIO_INC = -I$(srcdir)/../../rktio -I../../rktio
ALL_CFLAGS = $(CFLAGS) -I$(builddir)/.. -I$(srcdir)/../include $(RKTIO_INC) $(CPPFLAGS) @OPTIONS@ @MZOPTIONS@
OBJS = salloc.@LTO@ \
bignum.@LTO@ \
@ -303,7 +304,9 @@ SCONFIG = $(srcdir)/../sconfig.h $(srcdir)/../uconfig.h ../mzconfig.h
COMMON_HEADERS = $(srcdir)/schpriv.h $(srcdir)/schexn.h $(SCONFIG) $(srcdir)/../include/scheme.h \
$(srcdir)/../include/schthread.h $(srcdir)/mzrt.h $(srcdir)/mzrt_cas.inc \
$(srcdir)/longdouble/longdouble.h $(srcdir)/../utils/schiptr.h
$(srcdir)/longdouble/longdouble.h $(srcdir)/../utils/schiptr.h \
$(srcdir)/../../rktio/rktio.h $(srcdir)/../../rktio/rktio_platform.h \
../../rktio/rktio_config.h
JIT_HEADERS = $(srcdir)/jit.h $(srcdir)/jitfpu.h $(srcdir)/stypes.h \
$(srcdir)/lightning/i386/core.h $(srcdir)/lightning/i386/core-common.h \
$(srcdir)/lightning/i386/asm.h $(srcdir)/lightning/i386/asm-common.h \

View File

@ -625,6 +625,7 @@ Scheme_Env *scheme_place_instance_init(void *stack_base, struct NewGC *parent_gc
int *signal_fd;
GC_construct_child_gc(parent_gc, memory_limit);
# endif
scheme_rktio = rktio_init();
env = place_instance_init(stack_base, 0);
# if defined(MZ_PRECISE_GC)
signal_fd = scheme_get_signal_handle();

View File

@ -32,36 +32,7 @@
#include "schpriv.h"
#include "schexpobs.h"
#include "schmach.h"
/* The implementations of the time primitives, such as
`current-seconds', vary a lot from platform to platform. */
#ifdef USE_WIN32_TIME
# include <windows.h>
#else
# if defined(OSKIT) && !defined(OSKIT_TEST)
/* Get FreeBSD version, not oskit/time.h version */
# include <freebsd/time.h>
# endif
# include <time.h>
# include <sys/time.h>
# ifdef USE_GETRUSAGE
# include <sys/types.h>
# include <sys/time.h>
# include <sys/resource.h>
# include <errno.h>
# endif /* USE_GETRUSAGE */
# ifdef USE_SYSCALL_GETRUSAGE
# include <sys/syscall.h>
# define getrusage(a, b) syscall(SYS_GETRUSAGE, a, b)
# define USE_GETRUSAGE
# endif /* USE_SYSCALL_GETRUSAGE */
# ifdef WINDOWS_GET_PROCESS_TIMES
# include <windows.h>
# endif
# if !defined(USE_GETRUSAGE) && !defined(WINDOWS_GET_PROCESS_TIMES) && !defined(USER_TIME_IS_CLOCK)
# include <sys/times.h>
# endif
#endif /* USE_WIN32_TIME */
#include "schrktio.h"
static void ASSERT_SUSPEND_BREAK_ZERO() {
#if 0
@ -124,10 +95,6 @@ THREAD_LOCAL_DECL(static Scheme_Overflow *offstack_overflow);
THREAD_LOCAL_DECL(int scheme_cont_capture_count);
THREAD_LOCAL_DECL(static int scheme_prompt_capture_count);
#ifdef WINDOWS_GET_PROCESS_TIMES
SHARED_OK volatile uintptr_t scheme_process_children_msecs;
#endif
/* locals */
static Scheme_Object *procedure_p (int argc, Scheme_Object *argv[]);
static Scheme_Object *apply (int argc, Scheme_Object *argv[]);
@ -227,16 +194,6 @@ typedef void (*DW_PrePost_Proc)(void *);
static void register_traversers(void);
#endif
#ifdef USE_WIN32_TIME
typedef BOOL (WINAPI*GetTimeZoneInformationForYearProc_t)(USHORT wYear, void* pdtzi, LPTIME_ZONE_INFORMATION ptzi);
static GetTimeZoneInformationForYearProc_t GetTimeZoneInformationForYearProc;
typedef BOOL (WINAPI*SystemTimeToTzSpecificLocalTimeExProc_t)(void *lpTimeZoneInformation,
const SYSTEMTIME *lpUniversalTime,
LPSYSTEMTIME lpLocalTime);
static SystemTimeToTzSpecificLocalTimeExProc_t SystemTimeToTzSpecificLocalTimeExProc;
#endif
/* See call_cc: */
typedef struct Scheme_Dynamic_Wind_List {
MZTAG_IF_REQUIRED
@ -714,20 +671,6 @@ scheme_init_fun (Scheme_Env *env)
original_default_prompt = MALLOC_ONE_TAGGED(Scheme_Prompt);
original_default_prompt->so.type = scheme_prompt_type;
original_default_prompt->tag = scheme_default_prompt_tag;
#ifdef USE_WIN32_TIME
{
HMODULE hm;
hm = LoadLibrary("kernel32.dll");
GetTimeZoneInformationForYearProc
= (GetTimeZoneInformationForYearProc_t)GetProcAddress(hm, "GetTimeZoneInformationForYear");
SystemTimeToTzSpecificLocalTimeExProc
= (SystemTimeToTzSpecificLocalTimeExProc_t)GetProcAddress(hm, "SystemTimeToTzSpecificLocalTimeEx");
FreeLibrary(hm);
}
#endif
}
void
@ -9732,121 +9675,26 @@ static Scheme_Object *jump_to_alt_continuation()
/* time */
/*========================================================================*/
#ifndef CLOCKS_PER_SEC
#define CLOCKS_PER_SEC 1000000
#endif
#ifdef USE_WIN32_TIME
/* Number of milliseconds from 1601 to 1970: */
# define MSEC_OFFSET 11644473600000
mzlonglong get_hectonanoseconds_as_longlong()
{
FILETIME ft;
mzlonglong v;
GetSystemTimeAsFileTime(&ft);
v = ((mzlonglong)ft.dwHighDateTime << 32) | ft.dwLowDateTime;
v -= ((mzlonglong)MSEC_OFFSET * 10000);
return v;
}
#endif
intptr_t scheme_get_milliseconds(void)
XFORM_SKIP_PROC
/* this function can be called from any OS thread */
{
#ifdef USE_WIN32_TIME
return (intptr_t)(get_hectonanoseconds_as_longlong() / (mzlonglong)10000);
#else
struct timeval now;
gettimeofday(&now, NULL);
return now.tv_sec * 1000 + now.tv_usec / 1000;
#endif
return rktio_get_milliseconds();
}
double scheme_get_inexact_milliseconds(void)
XFORM_SKIP_PROC
/* this function can be called from any OS thread */
{
#ifdef USE_WIN32_TIME
mzlonglong v;
v = get_hectonanoseconds_as_longlong();
return (double)(v / 10000) + (((double)(v % 10000)) / 10000.0);
#else
struct timeval now;
gettimeofday(&now, NULL);
return (double)now.tv_sec * 1000.0 + (double)now.tv_usec / 1000;
#endif
return rktio_get_inexact_milliseconds();
}
intptr_t scheme_get_process_milliseconds(void)
XFORM_SKIP_PROC
{
#ifdef USER_TIME_IS_CLOCK
return scheme_get_milliseconds();
#else
# ifdef USE_GETRUSAGE
struct rusage use;
intptr_t s, u;
do {
if (!getrusage(RUSAGE_SELF, &use))
break;
} while (errno == EINTR);
s = use.ru_utime.tv_sec + use.ru_stime.tv_sec;
u = use.ru_utime.tv_usec + use.ru_stime.tv_usec;
return s * 1000 + u / 1000;
# else
# ifdef WINDOWS_GET_PROCESS_TIMES
{
FILETIME cr, ex, kr, us;
if (GetProcessTimes(GetCurrentProcess(), &cr, &ex, &kr, &us)) {
mzlonglong v;
v = ((((mzlonglong)kr.dwHighDateTime << 32) + kr.dwLowDateTime)
+ (((mzlonglong)us.dwHighDateTime << 32) + us.dwLowDateTime));
return (uintptr_t)(v / 10000);
} else
return 0; /* anything better to do? */
}
# else
return clock() * 1000 / CLOCKS_PER_SEC;
# endif
# endif
#endif
return rktio_get_process_milliseconds(scheme_rktio);
}
intptr_t scheme_get_process_children_milliseconds(void)
XFORM_SKIP_PROC
{
#ifdef USER_TIME_IS_CLOCK
return 0;
#else
# ifdef USE_GETRUSAGE
struct rusage use;
intptr_t s, u;
do {
if (!getrusage(RUSAGE_CHILDREN, &use))
break;
} while (errno == EINTR);
s = use.ru_utime.tv_sec + use.ru_stime.tv_sec;
u = use.ru_utime.tv_usec + use.ru_stime.tv_usec;
return (s * 1000 + u / 1000);
# else
# ifdef WINDOWS_GET_PROCESS_TIMES
return (intptr_t)scheme_process_children_msecs;
# else
clock_t t;
times(&t);
return (t.tms_cutime + t.tms_cstime) * 1000 / CLK_TCK;
# endif
# endif
#endif
return rktio_get_process_children_milliseconds(scheme_rktio);
}
intptr_t scheme_get_thread_milliseconds(Scheme_Object *thrd)
@ -9865,154 +9713,16 @@ intptr_t scheme_get_thread_milliseconds(Scheme_Object *thrd)
intptr_t scheme_get_seconds(void)
{
#ifdef USE_WIN32_TIME
return (intptr_t)(get_hectonanoseconds_as_longlong() / (mzlonglong)10000000);
#else
# ifdef USE_PLAIN_TIME
time_t now;
now = time(NULL);
return now;
# else
struct timeval now;
gettimeofday(&now, NULL);
return now.tv_sec;
# endif
#endif
return rktio_get_seconds(scheme_rktio);
}
#if defined(USE_WIN32_TIME)
/* Assuming not a leap year (and adjusted elsewhere): */
static int month_offsets[13] = { 0, 31, 59, 90,
120, 151, 181, 212,
243, 273, 304, 334,
365};
# define dtxCOMP(f) if (a->f < b->f) return 1; if (a->f > b->f) return 0;
static int is_start_day_before(SYSTEMTIME *a, SYSTEMTIME *b)
{
dtxCOMP(wYear);
/* When comparing DST boundaries, we expect to get here,
because wYear will be 0 to mean "every year". */
dtxCOMP(wMonth);
/* When comparing DST boundaries, it's unlikely that we'll get here,
because that would mean that StdT and DST start in the same month. */
dtxCOMP(wDay); /* for DST boundaires, this is a week number */
dtxCOMP(wDayOfWeek);
dtxCOMP(wHour);
dtxCOMP(wMinute);
return 0;
}
static int is_day_before(SYSTEMTIME *a, SYSTEMTIME *b)
/* a is a date, and b is a DST boundary spec */
{
int dos, doc;
if (b->wYear) {
dtxCOMP(wYear);
}
dtxCOMP(wMonth);
/* "Date" of a Sunday this month, 0 to 6: */
dos = ((a->wDay - a->wDayOfWeek) + 7) % 7;
/* Date of first b->wDayOfWeek this month, 1 to 7: */
doc = (dos + b->wDayOfWeek) % 7;
if (doc == 0) doc = 7;
/* Date of change this year: */
doc = doc + ((b->wDay - 1) * 7);
if (doc > (month_offsets[b->wMonth] - month_offsets[b->wMonth-1]))
doc -= 7;
/* Above assumes that a time change doesn't occur on a leap day! */
if (a->wDay < doc)
return 1;
if (a->wDay > doc)
return 0;
dtxCOMP(wHour);
dtxCOMP(wMinute);
return 0;
}
# undef dtxCOMP
#endif
#if (defined(OS_X) || defined(XONX)) && defined(__x86_64__)
/* work around a bug in localtime() in 10.6.8 */
# include <sys/param.h>
# include <sys/sysctl.h>
static int VALID_TIME_RANGE(UNBUNDLE_TIME_TYPE lnow)
{
/* Fits in 32 bits? */
int ilnow = (int)lnow;
if (lnow == (UNBUNDLE_TIME_TYPE)ilnow)
return 1;
/* 10.7 or later? */
{
int a[2];
size_t len;
char *vers;
a[0] = CTL_KERN;
a[1] = KERN_OSRELEASE;
sysctl(a, 2, NULL, &len, NULL, 0);
vers = (char *)scheme_malloc_atomic(len * sizeof(char));
sysctl(a, 2, vers, &len, NULL, 0);
if ((vers[0] == '1') && (vers[1] == '0') && (vers[2] == '.')) {
/* localtime() in 10.6.x (= 10.x at the kernel layer) doesn't seem
to work right with negative numbers that don't fit into 32 bits */
return 0;
}
}
return 1;
}
#else
# ifdef MIN_VALID_DATE_SECONDS
# define VALID_TIME_RANGE_MIN(x) ((x) >= MIN_VALID_DATE_SECONDS)
# else
# define VALID_TIME_RANGE_MIN(x) 1
# endif
# if defined(MAX_VALID_DATE_SECONDS_BITS) && defined(SIXTY_FOUR_BIT_INTEGERS)
# define VALID_TIME_RANGE_BITS(x) (((x) >= 0) \
? ((x) == ((x) & (((intptr_t)1 << MAX_VALID_DATE_SECONDS_BITS) - 1))) \
: ((-(x)) == ((-(x)) & (((intptr_t)1 << MAX_VALID_DATE_SECONDS_BITS) - 1))))
# else
# define VALID_TIME_RANGE_BITS(x) 1
# endif
# define VALID_TIME_RANGE(x) (VALID_TIME_RANGE_MIN(x) && VALID_TIME_RANGE_BITS(x))
#endif
static Scheme_Object *seconds_to_date(int argc, Scheme_Object **argv)
{
UNBUNDLE_TIME_TYPE lnow;
intptr_t lnow;
int get_gmt;
int hour, min, sec, month, day, wday, yday, dst;
intptr_t year;
long tzoffset;
#ifdef USE_WIN32_TIME
# define CHECK_TIME_T uintptr_t
SYSTEMTIME localTime;
#else
# define CHECK_TIME_T time_t
struct tm *localTime;
#endif
CHECK_TIME_T now;
char *tzn;
rktio_date_t *dt;
Scheme_Object *p[12], *secs, *nsecs, *zname;
char *tzn;
secs = argv[0];
@ -10042,168 +9752,40 @@ static Scheme_Object *seconds_to_date(int argc, Scheme_Object **argv)
secs = scheme_inexact_to_exact(1, p);
}
if (scheme_get_time_val(secs, &lnow)
&& (((UNBUNDLE_TIME_TYPE)(now = (CHECK_TIME_T)lnow)) == lnow)
&& VALID_TIME_RANGE(lnow)) {
int success;
#ifdef USE_WIN32_TIME
{
umzlonglong tmpC;
tmpC = ((umzlonglong)lnow * 10000000);
if ((mzlonglong)tmpC / 10000000 != lnow) {
/* overflow */
success = 0;
} else {
mzlonglong nsC;
FILETIME ft;
nsC = tmpC + ((umzlonglong)MSEC_OFFSET * 10000);
if (nsC < (mzlonglong)tmpC) {
/* overflow */
success = 0;
} else {
ft.dwLowDateTime = nsC & (mzlonglong)0xFFFFFFFF;
ft.dwHighDateTime = nsC >> 32;
success = FileTimeToSystemTime(&ft, &localTime);
if (success && !get_gmt) {
SYSTEMTIME t2 = localTime;
if (SystemTimeToTzSpecificLocalTimeExProc)
success = SystemTimeToTzSpecificLocalTimeExProc(NULL, &t2, &localTime);
else
success = SystemTimeToTzSpecificLocalTime(NULL, &t2, &localTime);
}
}
}
}
#else
if (get_gmt)
localTime = gmtime(&now);
else
localTime = localtime(&now);
success = !!localTime;
#endif
if (success) {
#ifdef USE_WIN32_TIME
hour = localTime.wHour;
min = localTime.wMinute;
sec = localTime.wSecond;
month = localTime.wMonth;
day = localTime.wDay;
year = localTime.wYear;
wday = localTime.wDayOfWeek;
yday = month_offsets[localTime.wMonth-1] + day-1;
/* leap-year adjustment: */
if ((month > 2)
&& ((year % 4) == 0)
&& (((year % 100) != 0) || ((year % 400) == 0)))
yday++;
dst = 0;
if (get_gmt) {
tzoffset = 0;
tzn = "UTC";
} else {
TIME_ZONE_INFORMATION tz;
if (GetTimeZoneInformationForYearProc)
GetTimeZoneInformationForYearProc(localTime.wYear, NULL, &tz);
else
(void)GetTimeZoneInformation(&tz);
if (tz.StandardDate.wMonth) {
if (is_start_day_before(&tz.DaylightDate, &tz.StandardDate)) {
/* northern hemisphere */
dst = (!is_day_before(&localTime, &tz.DaylightDate)
&& is_day_before(&localTime, &tz.StandardDate));
} else {
/* southern hemisphere */
dst = (is_day_before(&localTime, &tz.StandardDate)
|| !is_day_before(&localTime, &tz.DaylightDate));
}
}
if (dst) {
tzoffset = (tz.Bias + tz.DaylightBias) * -60;
tzn = NARROW_PATH(tz.DaylightName);
} else {
tzoffset = (tz.Bias + tz.StandardBias) * -60;
tzn = NARROW_PATH(tz.StandardName);
}
}
#else
hour = localTime->tm_hour;
min = localTime->tm_min;
sec = localTime->tm_sec;
month = localTime->tm_mon + 1;
day = localTime->tm_mday;
year = (uintptr_t)localTime->tm_year + 1900;
wday = localTime->tm_wday;
yday = localTime->tm_yday;
if (get_gmt)
dst = 0;
else
dst = localTime->tm_isdst;
tzoffset = 0;
if (!get_gmt) {
# ifdef USE_TIMEZONE_VAR
tzoffset = -MSC_IZE(timezone);
# endif
# ifdef USE_TOD_FOR_TIMEZONE
{
struct timezone xtz;
struct timeval xtv;
gettimeofday(&xtv, &xtz);
tzoffset = -(xtz.tz_minuteswest * 60);
}
# endif
# ifdef USE_TIMEZONE_VAR_W_DLS
tzoffset = -(MSCBOR_IZE(timezone) - (dst ? 3600 : 0));
# endif
# ifdef USE_TIMEZONE_AND_ALTZONE_VAR
if (dst)
tzoffset = -altzone;
else
tzoffset = -timezone;
# endif
# ifdef USE_TM_GMTOFF_FIELD
tzoffset = localTime->tm_gmtoff;
# endif
# ifdef USE_TZNAME_VAR
tzn = MSC_IZE(tzname)[localTime->tm_isdst];
# elif defined(USE_TM_ZONE_FIELD)
tzn = localTime->tm_zone;
# else
tzn = NULL;
# endif
} else
tzn = "UTC";
#endif
if (scheme_get_time_val(secs, &lnow)) {
dt = rktio_seconds_to_date(scheme_rktio, lnow, SCHEME_INT_VAL(nsecs), get_gmt);
if (dt) {
tzn = dt->zone_name;
if (!tzn)
tzn = "?";
zname = scheme_make_utf8_string(tzn);
SCHEME_SET_IMMUTABLE(zname);
p[0] = scheme_make_integer(sec);
p[1] = scheme_make_integer(min);
p[2] = scheme_make_integer(hour);
p[3] = scheme_make_integer(day);
p[4] = scheme_make_integer(month);
p[5] = scheme_make_integer(year);
p[6] = scheme_make_integer(wday);
p[7] = scheme_make_integer(yday);
p[8] = dst ? scheme_true : scheme_false;
p[9] = scheme_make_integer(tzoffset);
p[10] = nsecs;
p[0] = scheme_make_integer(dt->second);
p[1] = scheme_make_integer(dt->minute);
p[2] = scheme_make_integer(dt->hour);
p[3] = scheme_make_integer(dt->day);
p[4] = scheme_make_integer(dt->month);
p[5] = scheme_make_integer(dt->year);
p[6] = scheme_make_integer(dt->day_of_week);
p[7] = scheme_make_integer(dt->day_of_year);
p[8] = (dt->is_dst ? scheme_true : scheme_false);
p[9] = scheme_make_integer(dt->zone_offset);
p[10] = scheme_make_integer(dt->nanosecond);
p[11] = zname;
if (dt->zone_name)
rktio_free(dt->zone_name);
free(dt);
return scheme_make_struct_instance(scheme_date, 12, p);
} else if ((rktio_get_last_error(scheme_rktio) != RKTIO_ERROR_TIME_OUT_OF_RANGE)
|| (rktio_get_last_error_kind(scheme_rktio) != RKTIO_ERROR_KIND_RACKET)) {
scheme_raise_exn(MZEXN_FAIL,
"seconds->date: conversion error\n"
" error: %d; %s",
rktio_get_last_error(scheme_rktio),
rktio_get_last_error_string(scheme_rktio));
}
}

View File

@ -31,6 +31,7 @@
#include "schpriv.h"
#include <string.h>
#include "schgc.h"
#include "schrktio.h"
#ifdef DOS_FAR_POINTERS
# include <alloc.h>
@ -54,6 +55,8 @@
# include <windows.h>
#endif
THREAD_LOCAL_DECL(rktio_t *scheme_rktio);
THREAD_LOCAL_DECL(uintptr_t scheme_os_thread_id);
THREAD_LOCAL_DECL(static void **dgc_array);
@ -203,6 +206,8 @@ static int do_main_stack_setup(int no_auto_statics, Scheme_Nested_Main _main, vo
#endif
scheme_set_stack_base(PROMPT_STACK(stack_start), no_auto_statics);
scheme_rktio = rktio_init();
return_code = _main(data);

View File

@ -215,6 +215,7 @@ Scheme_Object *scheme_dump_gc_stats(int c, Scheme_Object *p[]);
#define REGISTER_SO(x) MZ_REGISTER_STATIC(x)
THREAD_LOCAL_DECL(extern struct rktio_t *rktio);
THREAD_LOCAL_DECL(extern int scheme_current_place_id);
THREAD_LOCAL_DECL(extern intptr_t scheme_total_gc_time);
THREAD_LOCAL_DECL(extern int scheme_cont_capture_count);

View File

@ -0,0 +1,2 @@
#define RKTIO_EXTERN XFORM_NONGCING extern
#include "rktio.h"

View File

@ -3,16 +3,20 @@
#include "rktio_config.h"
#ifndef RKTIO_EXTERN
# define RKTIO_EXTERN extern
#endif
/* A rktio_t value represents an instance of the Racket I/O system.
Almost every rktio_...() function takes it as the first argument. */
typedef struct rktio_t rktio_t;
rktio_t *rktio_init(void);
void rktio_destroy(rktio_t *);
RKTIO_EXTERN rktio_t *rktio_init(void);
RKTIO_EXTERN void rktio_destroy(rktio_t *);
/* Normally equivalent to free(), but ensures the same malloc()/free()
that rktio function use: */
void rktio_free(void *p);
RKTIO_EXTERN void rktio_free(void *p);
/*************************************************/
/* Reading and writing files */
@ -35,21 +39,21 @@ typedef struct rktio_fd_t rktio_fd_t;
are specified, then the value is inferred */
/* A socket registered this way should be non-blocking: */
rktio_fd_t *rktio_system_fd(rktio_t *rktio, intptr_t system_fd, int modes);
intptr_t rktio_fd_system_fd(rktio_t *rktio, rktio_fd_t *rfd);
RKTIO_EXTERN rktio_fd_t *rktio_system_fd(rktio_t *rktio, intptr_t system_fd, int modes);
RKTIO_EXTERN intptr_t rktio_fd_system_fd(rktio_t *rktio, rktio_fd_t *rfd);
int rktio_fd_is_regular_file(rktio_t *rktio, rktio_fd_t *rfd);
int rktio_fd_is_socket(rktio_t *rktio, rktio_fd_t *rfd);
int rktio_fd_is_udp(rktio_t *rktio, rktio_fd_t *rfd);
int rktio_fd_is_terminal(rktio_t *rktio, rktio_fd_t *rfd);
RKTIO_EXTERN int rktio_fd_is_regular_file(rktio_t *rktio, rktio_fd_t *rfd);
RKTIO_EXTERN int rktio_fd_is_socket(rktio_t *rktio, rktio_fd_t *rfd);
RKTIO_EXTERN int rktio_fd_is_udp(rktio_t *rktio, rktio_fd_t *rfd);
RKTIO_EXTERN int rktio_fd_is_terminal(rktio_t *rktio, rktio_fd_t *rfd);
int rktio_fd_modes(rktio_t *rktio, rktio_fd_t *rfd);
RKTIO_EXTERN int rktio_fd_modes(rktio_t *rktio, rktio_fd_t *rfd);
rktio_fd_t *rktio_open(rktio_t *rktio, char *src, int modes);
int rktio_close(rktio_t *rktio, rktio_fd_t *fd);
RKTIO_EXTERN rktio_fd_t *rktio_open(rktio_t *rktio, char *src, int modes);
RKTIO_EXTERN int rktio_close(rktio_t *rktio, rktio_fd_t *fd);
rktio_fd_t *rktio_dup(rktio_t *rktio, rktio_fd_t *rfd);
void rktio_forget(rktio_t *rktio, rktio_fd_t *fd);
RKTIO_EXTERN rktio_fd_t *rktio_dup(rktio_t *rktio, rktio_fd_t *rfd);
RKTIO_EXTERN void rktio_forget(rktio_t *rktio, rktio_fd_t *fd);
#define RKTIO_READ_EOF (-1)
#define RKTIO_READ_ERROR (-2)
@ -57,18 +61,18 @@ void rktio_forget(rktio_t *rktio, rktio_fd_t *fd);
#define RKTIO_POLL_ERROR (-2)
#define RKTIO_POLL_READY 1
intptr_t rktio_read(rktio_t *rktio, rktio_fd_t *fd, char *buffer, intptr_t len);
intptr_t rktio_write(rktio_t *rktio, rktio_fd_t *fd, char *buffer, intptr_t len);
RKTIO_EXTERN intptr_t rktio_read(rktio_t *rktio, rktio_fd_t *fd, char *buffer, intptr_t len);
RKTIO_EXTERN intptr_t rktio_write(rktio_t *rktio, rktio_fd_t *fd, char *buffer, intptr_t len);
int rktio_poll_read_ready(rktio_t *rktio, rktio_fd_t *rfd);
int rktio_poll_write_ready(rktio_t *rktio, rktio_fd_t *rfd);
int rktio_poll_write_flushed(rktio_t *rktio, rktio_fd_t *rfd);
RKTIO_EXTERN int rktio_poll_read_ready(rktio_t *rktio, rktio_fd_t *rfd);
RKTIO_EXTERN int rktio_poll_write_ready(rktio_t *rktio, rktio_fd_t *rfd);
RKTIO_EXTERN int rktio_poll_write_flushed(rktio_t *rktio, rktio_fd_t *rfd);
#define RKTIO_LOCK_ERROR (-2)
#define RKTIO_LOCK_ACQUIRED 1
int rktio_file_lock_try(rktio_t *rktio, rktio_fd_t *rfd, int excl);
int rktio_file_unlock(rktio_t *rktio, rktio_fd_t *rfd);
RKTIO_EXTERN int rktio_file_lock_try(rktio_t *rktio, rktio_fd_t *rfd, int excl);
RKTIO_EXTERN int rktio_file_unlock(rktio_t *rktio, rktio_fd_t *rfd);
/*************************************************/
/* Network */
@ -76,16 +80,16 @@ int rktio_file_unlock(rktio_t *rktio, rktio_fd_t *rfd);
typedef struct rktio_addrinfo_lookup_t rktio_addrinfo_lookup_t;
typedef struct rktio_addrinfo_t rktio_addrinfo_t;
int rktio_get_ipv4_family(rktio_t *rktio);
RKTIO_EXTERN int rktio_get_ipv4_family(rktio_t *rktio);
rktio_addrinfo_lookup_t *rktio_start_addrinfo_lookup(rktio_t *rktio,
const char *hostname, int portno,
int family, int passive, int tcp);
int rktio_poll_addrinfo_lookup_ready(rktio_t *rktio, rktio_addrinfo_lookup_t *lookup);
rktio_addrinfo_t *rktio_addrinfo_lookup_get(rktio_t *rktio, rktio_addrinfo_lookup_t *lookup);
void rktio_addrinfo_lookup_stop(rktio_t *rktio, rktio_addrinfo_lookup_t *lookup);
RKTIO_EXTERN rktio_addrinfo_lookup_t *rktio_start_addrinfo_lookup(rktio_t *rktio,
const char *hostname, int portno,
int family, int passive, int tcp);
RKTIO_EXTERN int rktio_poll_addrinfo_lookup_ready(rktio_t *rktio, rktio_addrinfo_lookup_t *lookup);
RKTIO_EXTERN rktio_addrinfo_t *rktio_addrinfo_lookup_get(rktio_t *rktio, rktio_addrinfo_lookup_t *lookup);
RKTIO_EXTERN void rktio_addrinfo_lookup_stop(rktio_t *rktio, rktio_addrinfo_lookup_t *lookup);
void rktio_free_addrinfo(rktio_t *rktio, struct rktio_addrinfo_t *a);
RKTIO_EXTERN void rktio_free_addrinfo(rktio_t *rktio, struct rktio_addrinfo_t *a);
typedef struct rktio_listener_t rktio_listener_t;
typedef struct rktio_connect_t rktio_connect_t;
@ -93,80 +97,79 @@ typedef struct rktio_connect_t rktio_connect_t;
#define RKTIO_SHUTDOWN_READ RKTIO_OPEN_READ
#define RKTIO_SHUTDOWN_WRITE RKTIO_OPEN_WRITE
rktio_listener_t *rktio_listen(rktio_t *rktio, rktio_addrinfo_t *local, int backlog, int reuse);
void rktio_listen_stop(rktio_t *rktio, rktio_listener_t *l);
int rktio_poll_accept_ready(rktio_t *rktio, rktio_listener_t *listener);
rktio_fd_t *rktio_accept(rktio_t *rktio, rktio_listener_t *listener);
RKTIO_EXTERN rktio_listener_t *rktio_listen(rktio_t *rktio, rktio_addrinfo_t *local, int backlog, int reuse);
RKTIO_EXTERN void rktio_listen_stop(rktio_t *rktio, rktio_listener_t *l);
RKTIO_EXTERN int rktio_poll_accept_ready(rktio_t *rktio, rktio_listener_t *listener);
RKTIO_EXTERN rktio_fd_t *rktio_accept(rktio_t *rktio, rktio_listener_t *listener);
/* Addreses must not be freed until the connection is complete or stopped: */
rktio_connect_t *rktio_start_connect(rktio_t *rktio, rktio_addrinfo_t *remote, rktio_addrinfo_t *local);
RKTIO_EXTERN rktio_connect_t *rktio_start_connect(rktio_t *rktio, rktio_addrinfo_t *remote, rktio_addrinfo_t *local);
/* A `RKTIO_ERROR_CONNECT_TRYING_NEXT` error effectively means "try again",
and the connection object is still valid: */
rktio_fd_t *rktio_connect_finish(rktio_t *rktio, rktio_connect_t *conn);
void rktio_connect_stop(rktio_t *rktio, rktio_connect_t *conn);
int rktio_poll_connect_ready(rktio_t *rktio, rktio_connect_t *conn);
RKTIO_EXTERN rktio_fd_t *rktio_connect_finish(rktio_t *rktio, rktio_connect_t *conn);
RKTIO_EXTERN void rktio_connect_stop(rktio_t *rktio, rktio_connect_t *conn);
RKTIO_EXTERN int rktio_poll_connect_ready(rktio_t *rktio, rktio_connect_t *conn);
int rktio_socket_shutdown(rktio_t *rktio, rktio_fd_t *rfd, int mode);
RKTIO_EXTERN int rktio_socket_shutdown(rktio_t *rktio, rktio_fd_t *rfd, int mode);
rktio_fd_t *rktio_udp_open(rktio_t *rktio, rktio_addrinfo_t *addr);
int rktio_udp_disconnect(rktio_t *rktio, rktio_fd_t *rfd);
int rktio_udp_bind(rktio_t *rktio, rktio_fd_t *rfd, rktio_addrinfo_t *addr);
int rktio_udp_connect(rktio_t *rktio, rktio_fd_t *rfd, rktio_addrinfo_t *addr);
RKTIO_EXTERN rktio_fd_t *rktio_udp_open(rktio_t *rktio, rktio_addrinfo_t *addr);
RKTIO_EXTERN int rktio_udp_disconnect(rktio_t *rktio, rktio_fd_t *rfd);
RKTIO_EXTERN int rktio_udp_bind(rktio_t *rktio, rktio_fd_t *rfd, rktio_addrinfo_t *addr);
RKTIO_EXTERN int rktio_udp_connect(rktio_t *rktio, rktio_fd_t *rfd, rktio_addrinfo_t *addr);
intptr_t rktio_udp_sendto(rktio_t *rktio, rktio_fd_t *rfd, rktio_addrinfo_t *addr,
char *buffer, intptr_t len);
RKTIO_EXTERN intptr_t rktio_udp_sendto(rktio_t *rktio, rktio_fd_t *rfd, rktio_addrinfo_t *addr,
char *buffer, intptr_t len);
typedef struct rktio_length_and_addrinfo_t {
intptr_t len;
rktio_addrinfo_t *addr;
} rktio_length_and_addrinfo_t;
rktio_length_and_addrinfo_t *rktio_udp_recvfrom(rktio_t *rktio, rktio_fd_t *rfd, char *buffer, intptr_t len);
RKTIO_EXTERN rktio_length_and_addrinfo_t *rktio_udp_recvfrom(rktio_t *rktio, rktio_fd_t *rfd, char *buffer, intptr_t len);
#define RKTIO_PROP_ERROR (-2)
/* The following accessors return RKTIO_PROP_ERROR on failure */
int rktio_udp_get_multicast_loopback(rktio_t *rktio, rktio_fd_t *rfd);
int rktio_udp_set_multicast_loopback(rktio_t *rktio, rktio_fd_t *rfd, int on);
int rktio_udp_get_multicast_ttl(rktio_t *rktio, rktio_fd_t *rfd);
int rktio_udp_set_multicast_ttl(rktio_t *rktio, rktio_fd_t *rfd, int ttl_val);
RKTIO_EXTERN int rktio_udp_get_multicast_loopback(rktio_t *rktio, rktio_fd_t *rfd);
RKTIO_EXTERN int rktio_udp_set_multicast_loopback(rktio_t *rktio, rktio_fd_t *rfd, int on);
RKTIO_EXTERN int rktio_udp_get_multicast_ttl(rktio_t *rktio, rktio_fd_t *rfd);
RKTIO_EXTERN int rktio_udp_set_multicast_ttl(rktio_t *rktio, rktio_fd_t *rfd, int ttl_val);
RKTIO_EXTERN char **rktio_socket_address(rktio_t *rktio, rktio_fd_t *rfd);
RKTIO_EXTERN char **rktio_socket_peer_address(rktio_t *rktio, rktio_fd_t *rfd);
char **rktio_socket_address(rktio_t *rktio, rktio_fd_t *rfd);
char **rktio_socket_peer_address(rktio_t *rktio, rktio_fd_t *rfd);
char *rktio_udp_multicast_interface(rktio_t *rktio, rktio_fd_t *rfd);
int rktio_udp_set_multicast_interface(rktio_t *rktio, rktio_fd_t *rfd, rktio_addrinfo_t *addr);
RKTIO_EXTERN char *rktio_udp_multicast_interface(rktio_t *rktio, rktio_fd_t *rfd);
RKTIO_EXTERN int rktio_udp_set_multicast_interface(rktio_t *rktio, rktio_fd_t *rfd, rktio_addrinfo_t *addr);
enum {
RKTIO_ADD_MEMBERSHIP,
RKTIO_DROP_MEMBERSHIP
};
int rktio_udp_change_multicast_group(rktio_t *rktio, rktio_fd_t *rfd,
rktio_addrinfo_t *group_addr,
rktio_addrinfo_t *intf_addr,
int action);
RKTIO_EXTERN int rktio_udp_change_multicast_group(rktio_t *rktio, rktio_fd_t *rfd,
rktio_addrinfo_t *group_addr,
rktio_addrinfo_t *intf_addr,
int action);
/*************************************************/
/* Environment variables */
typedef struct rktio_envvars_t rktio_envvars_t;
char *rktio_getenv(rktio_t *rktio, char *name);
int rktio_setenv(rktio_t *rktio, const char *name, const char *val);
RKTIO_EXTERN char *rktio_getenv(rktio_t *rktio, char *name);
RKTIO_EXTERN int rktio_setenv(rktio_t *rktio, const char *name, const char *val);
rktio_envvars_t *rktio_envvars(rktio_t *rktio);
rktio_envvars_t *rktio_empty_envvars(rktio_t *rktio);
rktio_envvars_t *rktio_envvars_copy(rktio_t *rktio, rktio_envvars_t *envvars);
void rktio_envvars_free(rktio_t *rktio, rktio_envvars_t *envvars);
RKTIO_EXTERN rktio_envvars_t *rktio_envvars(rktio_t *rktio);
RKTIO_EXTERN rktio_envvars_t *rktio_empty_envvars(rktio_t *rktio);
RKTIO_EXTERN rktio_envvars_t *rktio_envvars_copy(rktio_t *rktio, rktio_envvars_t *envvars);
RKTIO_EXTERN void rktio_envvars_free(rktio_t *rktio, rktio_envvars_t *envvars);
char *rktio_envvars_get(rktio_t *rktio, rktio_envvars_t *envvars, char *name);
void rktio_envvars_set(rktio_t *rktio, rktio_envvars_t *envvars, char *name, char *value);
RKTIO_EXTERN char *rktio_envvars_get(rktio_t *rktio, rktio_envvars_t *envvars, char *name);
RKTIO_EXTERN void rktio_envvars_set(rktio_t *rktio, rktio_envvars_t *envvars, char *name, char *value);
intptr_t rktio_envvars_count(rktio_t *rktio, rktio_envvars_t *envvars);
char *rktio_envvars_name_ref(rktio_t *rktio, rktio_envvars_t *envvars, intptr_t i);
char *rktio_envvars_value_ref(rktio_t *rktio, rktio_envvars_t *envvars, intptr_t i);
RKTIO_EXTERN intptr_t rktio_envvars_count(rktio_t *rktio, rktio_envvars_t *envvars);
RKTIO_EXTERN char *rktio_envvars_name_ref(rktio_t *rktio, rktio_envvars_t *envvars, intptr_t i);
RKTIO_EXTERN char *rktio_envvars_value_ref(rktio_t *rktio, rktio_envvars_t *envvars, intptr_t i);
/*************************************************/
/* Processes */
@ -183,30 +186,30 @@ typedef struct rktio_process_result_t {
rktio_fd_t *stdin_fd, *stdout_fd, *stderr_fd;
} rktio_process_result_t;
rktio_process_result_t *rktio_process(rktio_t *rktio,
const char *command, int argc, char **argv,
rktio_fd_t *stdout_fd, rktio_fd_t *stdin_fd, rktio_fd_t *stderr_fd,
const char *current_directory, rktio_envvars_t *envvars,
int flags,
void (*unix_child_process_callback)());
RKTIO_EXTERN rktio_process_result_t *rktio_process(rktio_t *rktio,
const char *command, int argc, char **argv,
rktio_fd_t *stdout_fd, rktio_fd_t *stdin_fd, rktio_fd_t *stderr_fd,
const char *current_directory, rktio_envvars_t *envvars,
int flags,
void (*unix_child_process_callback)());
int rktio_process_kill(rktio_t *rktio, rktio_process_t *sp);
int rktio_process_interrupt(rktio_t *rktio, rktio_process_t *sp);
void rktio_process_forget(rktio_t *rktio, rktio_process_t *sp);
RKTIO_EXTERN int rktio_process_kill(rktio_t *rktio, rktio_process_t *sp);
RKTIO_EXTERN int rktio_process_interrupt(rktio_t *rktio, rktio_process_t *sp);
RKTIO_EXTERN void rktio_process_forget(rktio_t *rktio, rktio_process_t *sp);
#define RKTIO_PROCESS_ERROR (-2)
#define RKTIO_PROCESS_DONE 1
int rktio_poll_process_done(rktio_t *rktio, rktio_process_t *sp);
RKTIO_EXTERN int rktio_poll_process_done(rktio_t *rktio, rktio_process_t *sp);
typedef struct rktio_status_t {
int running;
int result;
} rktio_status_t;
rktio_status_t *rktio_process_status(rktio_t *rktio, rktio_process_t *sp);
RKTIO_EXTERN rktio_status_t *rktio_process_status(rktio_t *rktio, rktio_process_t *sp);
void rktio_block_child_signals(rktio_t*rktio, int block);
RKTIO_EXTERN void rktio_block_child_signals(rktio_t*rktio, int block);
/*************************************************/
/* Filesystem-change events */
@ -216,13 +219,13 @@ void rktio_block_child_signals(rktio_t*rktio, int block);
#define RKTIO_FS_CHANGE_LOW_LATENCY (1 << 2)
#define RKTIO_FS_CHANGE_FILE_LEVEL (1 << 3)
int rktio_fs_change_properties(rktio_t *rktio);
RKTIO_EXTERN int rktio_fs_change_properties(rktio_t *rktio);
typedef struct rktio_fs_change_t rktio_fs_change_t;
rktio_fs_change_t *rktio_fs_change(rktio_t *rktio, char *path);
void rktio_fs_change_forget(rktio_t *rktio, rktio_fs_change_t *fc);
int rktio_poll_fs_change_ready(rktio_t *rktio, rktio_fs_change_t *fc);
RKTIO_EXTERN rktio_fs_change_t *rktio_fs_change(rktio_t *rktio, char *path);
RKTIO_EXTERN void rktio_fs_change_forget(rktio_t *rktio, rktio_fs_change_t *fc);
RKTIO_EXTERN int rktio_poll_fs_change_ready(rktio_t *rktio, rktio_fs_change_t *fc);
/*************************************************/
/* File-descriptor sets for polling */
@ -235,21 +238,21 @@ typedef struct rktio_poll_set_t rktio_poll_set_t;
#define RKTIO_POLL_READ RKTIO_OPEN_READ
#define RKTIO_POLL_WRITE RKTIO_OPEN_WRITE
rktio_poll_set_t *rktio_make_poll_set(rktio_t *rktio);
void rktio_poll_set_close(rktio_t *rktio, rktio_poll_set_t *fds);
RKTIO_EXTERN rktio_poll_set_t *rktio_make_poll_set(rktio_t *rktio);
RKTIO_EXTERN void rktio_poll_set_close(rktio_t *rktio, rktio_poll_set_t *fds);
void rktio_poll_add(rktio_t *rktio, rktio_fd_t *rfd, rktio_poll_set_t *fds, int modes);
void rktio_poll_add_receive(rktio_t *rktio, rktio_listener_t *listener, rktio_poll_set_t *fds);
void rktio_poll_add_connect(rktio_t *rktio, rktio_connect_t *conn, rktio_poll_set_t *fds);
void rktio_poll_add_addrinfo_lookup(rktio_t *rktio, rktio_addrinfo_lookup_t *lookup, rktio_poll_set_t *fds);
void rktio_poll_add_process(rktio_t *rktio, rktio_process_t *sp, rktio_poll_set_t *fds);
void rktio_poll_add_fs_change(rktio_t *rktio, rktio_fs_change_t *fc, rktio_poll_set_t *fds);
RKTIO_EXTERN void rktio_poll_add(rktio_t *rktio, rktio_fd_t *rfd, rktio_poll_set_t *fds, int modes);
RKTIO_EXTERN void rktio_poll_add_receive(rktio_t *rktio, rktio_listener_t *listener, rktio_poll_set_t *fds);
RKTIO_EXTERN void rktio_poll_add_connect(rktio_t *rktio, rktio_connect_t *conn, rktio_poll_set_t *fds);
RKTIO_EXTERN void rktio_poll_add_addrinfo_lookup(rktio_t *rktio, rktio_addrinfo_lookup_t *lookup, rktio_poll_set_t *fds);
RKTIO_EXTERN void rktio_poll_add_process(rktio_t *rktio, rktio_process_t *sp, rktio_poll_set_t *fds);
RKTIO_EXTERN void rktio_poll_add_fs_change(rktio_t *rktio, rktio_fs_change_t *fc, rktio_poll_set_t *fds);
void rktio_poll_set_add_nosleep(rktio_t *rktio, rktio_poll_set_t *fds);
RKTIO_EXTERN void rktio_poll_set_add_nosleep(rktio_t *rktio, rktio_poll_set_t *fds);
#ifdef RKTIO_SYSTEM_WINDOWS
void rktio_poll_set_add_handle(rktio_t *rktio, intptr_t h, rktio_poll_set_t *fds, int repost);
void rktio_poll_set_add_eventmask(rktio_t *rktio, rktio_poll_set_t *fds, int mask);
RKTIO_EXTERN void rktio_poll_set_add_handle(rktio_t *rktio, intptr_t h, rktio_poll_set_t *fds, int repost);
RKTIO_EXTERN void rktio_poll_set_add_eventmask(rktio_t *rktio, rktio_poll_set_t *fds, int mask);
#endif
/*************************************************/
@ -274,36 +277,36 @@ enum {
RKTIO_LTPS_REMOVE_VNODE
};
rktio_ltps_t *rktio_open_ltps(rktio_t *rktio);
int rktio_ltps_close(rktio_t *rktio, rktio_ltps_t *lt);
RKTIO_EXTERN rktio_ltps_t *rktio_open_ltps(rktio_t *rktio);
RKTIO_EXTERN int rktio_ltps_close(rktio_t *rktio, rktio_ltps_t *lt);
rktio_ltps_handle_t *rktio_ltps_add(rktio_t *rktio, rktio_ltps_t *lt, rktio_fd_t *rfd, int mode);
void rktio_ltps_handle_set_data(rktio_ltps_t *lt, rktio_ltps_handle_t *s, void *data);
void *rktio_ltps_handle_get_data(rktio_ltps_t *lt, rktio_ltps_handle_t *s);
RKTIO_EXTERN rktio_ltps_handle_t *rktio_ltps_add(rktio_t *rktio, rktio_ltps_t *lt, rktio_fd_t *rfd, int mode);
RKTIO_EXTERN void rktio_ltps_handle_set_data(rktio_ltps_t *lt, rktio_ltps_handle_t *s, void *data);
RKTIO_EXTERN void *rktio_ltps_handle_get_data(rktio_ltps_t *lt, rktio_ltps_handle_t *s);
int rktio_ltps_poll(rktio_t *rktio, rktio_ltps_t *lt);
rktio_ltps_handle_t *rktio_ltps_get_signaled_handle(rktio_t *rktio, rktio_ltps_t *lt);
RKTIO_EXTERN int rktio_ltps_poll(rktio_t *rktio, rktio_ltps_t *lt);
RKTIO_EXTERN rktio_ltps_handle_t *rktio_ltps_get_signaled_handle(rktio_t *rktio, rktio_ltps_t *lt);
void rktio_sleep(rktio_t *rktio, float nsecs, rktio_poll_set_t *fds, rktio_ltps_t *lt);
RKTIO_EXTERN void rktio_sleep(rktio_t *rktio, float nsecs, rktio_poll_set_t *fds, rktio_ltps_t *lt);
/*************************************************/
/* Files, directories, and links */
int rktio_file_exists(rktio_t *rktio, char *filename);
int rktio_directory_exists(rktio_t *rktio, char *dirname);
int rktio_link_exists(rktio_t *rktio, char *filename);
int rktio_is_regular_file(rktio_t *rktio, char *filename);
RKTIO_EXTERN int rktio_file_exists(rktio_t *rktio, char *filename);
RKTIO_EXTERN int rktio_directory_exists(rktio_t *rktio, char *dirname);
RKTIO_EXTERN int rktio_link_exists(rktio_t *rktio, char *filename);
RKTIO_EXTERN int rktio_is_regular_file(rktio_t *rktio, char *filename);
int rktio_delete_file(rktio_t *rktio, char *fn, int enable_write_on_fail);
int rktio_rename_file(rktio_t *rktio, char *dest, char *src, int exists_ok);
RKTIO_EXTERN int rktio_delete_file(rktio_t *rktio, char *fn, int enable_write_on_fail);
RKTIO_EXTERN int rktio_rename_file(rktio_t *rktio, char *dest, char *src, int exists_ok);
char *rktio_get_current_directory(rktio_t *rktio);
int rktio_set_current_directory(rktio_t *rktio, const char *path);
int rktio_make_directory(rktio_t *rktio, char *filename);
int rktio_delete_directory(rktio_t *rktio, char *filename, char *current_directory, int enable_write_on_fail);
RKTIO_EXTERN char *rktio_get_current_directory(rktio_t *rktio);
RKTIO_EXTERN int rktio_set_current_directory(rktio_t *rktio, const char *path);
RKTIO_EXTERN int rktio_make_directory(rktio_t *rktio, char *filename);
RKTIO_EXTERN int rktio_delete_directory(rktio_t *rktio, char *filename, char *current_directory, int enable_write_on_fail);
char *rktio_readlink(rktio_t *rktio, char *fullfilename);
int rktio_make_link(rktio_t *rktio, char *src, char *dest, int dest_is_directory);
RKTIO_EXTERN char *rktio_readlink(rktio_t *rktio, char *fullfilename);
RKTIO_EXTERN int rktio_make_link(rktio_t *rktio, char *src, char *dest, int dest_is_directory);
/*************************************************/
/* File attributes */
@ -318,13 +321,13 @@ typedef struct {
uintptr_t a, b, c;
} rktio_identity_t;
rktio_size_t *rktio_file_size(rktio_t *rktio, char *filename);
RKTIO_EXTERN rktio_size_t *rktio_file_size(rktio_t *rktio, char *filename);
rktio_timestamp_t *rktio_get_file_modify_seconds(rktio_t *rktio, char *file);
int rktio_set_file_modify_seconds(rktio_t *rktio, char *file, rktio_timestamp_t secs);
RKTIO_EXTERN rktio_timestamp_t *rktio_get_file_modify_seconds(rktio_t *rktio, char *file);
RKTIO_EXTERN int rktio_set_file_modify_seconds(rktio_t *rktio, char *file, rktio_timestamp_t secs);
rktio_identity_t *rktio_fd_identity(rktio_t *rktio, rktio_fd_t *fd);
rktio_identity_t *rktio_path_identity(rktio_t *rktio, char *path, int follow_links);
RKTIO_EXTERN rktio_identity_t *rktio_fd_identity(rktio_t *rktio, rktio_fd_t *fd);
RKTIO_EXTERN rktio_identity_t *rktio_path_identity(rktio_t *rktio, char *path, int follow_links);
/*************************************************/
/* Permissions */
@ -334,28 +337,28 @@ rktio_identity_t *rktio_path_identity(rktio_t *rktio, char *path, int follow_lin
#define RKTIO_PERMISSION_WRITE 0x2
#define RKTIO_PERMISSION_EXEC 0x1
int rktio_get_file_or_directory_permissions(rktio_t *rktio, char *filename, int all_bits);
int rktio_set_file_or_directory_permissions(rktio_t *rktio, char *filename, int new_bits);
RKTIO_EXTERN int rktio_get_file_or_directory_permissions(rktio_t *rktio, char *filename, int all_bits);
RKTIO_EXTERN int rktio_set_file_or_directory_permissions(rktio_t *rktio, char *filename, int new_bits);
/*************************************************/
/* Directory listing */
typedef struct rktio_directory_list_t rktio_directory_list_t;
rktio_directory_list_t *rktio_directory_list_start(rktio_t *rktio, char *filename, int is_drive);
char *rktio_directory_list_step(rktio_t *rktio, rktio_directory_list_t *dl);
RKTIO_EXTERN rktio_directory_list_t *rktio_directory_list_start(rktio_t *rktio, char *filename, int is_drive);
RKTIO_EXTERN char *rktio_directory_list_step(rktio_t *rktio, rktio_directory_list_t *dl);
char **rktio_filesystem_root_list(rktio_t *rktio);
RKTIO_EXTERN char **rktio_filesystem_root_list(rktio_t *rktio);
/*************************************************/
/* File copying */
typedef struct rktio_file_copy_t rktio_file_copy_t;
rktio_file_copy_t *rktio_copy_file_start(rktio_t *rktio, char *dest, char *src, int exists_ok);
int rktio_copy_file_is_done(rktio_t *rktio, rktio_file_copy_t *fc);
int rktio_copy_file_step(rktio_t *rktio, rktio_file_copy_t *fc);
void rktio_copy_file_stop(rktio_t *rktio, rktio_file_copy_t *fc);
RKTIO_EXTERN rktio_file_copy_t *rktio_copy_file_start(rktio_t *rktio, char *dest, char *src, int exists_ok);
RKTIO_EXTERN int rktio_copy_file_is_done(rktio_t *rktio, rktio_file_copy_t *fc);
RKTIO_EXTERN int rktio_copy_file_step(rktio_t *rktio, rktio_file_copy_t *fc);
RKTIO_EXTERN void rktio_copy_file_stop(rktio_t *rktio, rktio_file_copy_t *fc);
/*************************************************/
/* System paths */
@ -373,17 +376,17 @@ enum {
RKTIO_PATH_INIT_FILE
};
char *rktio_system_path(rktio_t *rktio, int which);
char *rktio_expand_user_tilde(rktio_t *rktio, char *filename);
RKTIO_EXTERN char *rktio_system_path(rktio_t *rktio, int which);
RKTIO_EXTERN char *rktio_expand_user_tilde(rktio_t *rktio, char *filename);
/*************************************************/
/* Sleep and signals */
typedef struct rktio_signal_handle_t rktio_signal_handle_t;
rktio_signal_handle_t *rktio_get_signal_handle(rktio_t *rktio);
void rktio_signal_received_at(rktio_signal_handle_t *h);
void rktio_signal_received(rktio_t *rktio);
RKTIO_EXTERN rktio_signal_handle_t *rktio_get_signal_handle(rktio_t *rktio);
RKTIO_EXTERN void rktio_signal_received_at(rktio_signal_handle_t *h);
RKTIO_EXTERN void rktio_signal_received(rktio_t *rktio);
/*************************************************/
/* Time and date */
@ -398,14 +401,14 @@ typedef struct rktio_date_t {
char *zone_name; /* can be NULL */
} rktio_date_t;
intptr_t rktio_get_milliseconds(void);
double rktio_get_inexact_milliseconds(void);
RKTIO_EXTERN intptr_t rktio_get_milliseconds(void);
RKTIO_EXTERN double rktio_get_inexact_milliseconds(void);
intptr_t rktio_get_process_milliseconds(rktio_t *rktio);
intptr_t scheme_get_process_children_milliseconds(rktio_t *rktio);
RKTIO_EXTERN intptr_t rktio_get_process_milliseconds(rktio_t *rktio);
RKTIO_EXTERN intptr_t rktio_get_process_children_milliseconds(rktio_t *rktio);
intptr_t rktio_get_seconds(rktio_t *rktio);
rktio_date_t *rktio_seconds_to_date(rktio_t *rktio, intptr_t seconds, intptr_t nanoseconds, int get_gmt);
RKTIO_EXTERN intptr_t rktio_get_seconds(rktio_t *rktio);
RKTIO_EXTERN rktio_date_t *rktio_seconds_to_date(rktio_t *rktio, intptr_t seconds, intptr_t nanoseconds, int get_gmt);
/*************************************************/
/* Errors */
@ -448,10 +451,13 @@ enum {
RKTIO_ERROR_LOCAL_HOST_NOT_FOUND,
};
int rktio_get_last_error(rktio_t *rktio);
int rktio_get_last_error_kind(rktio_t *rktio);
RKTIO_EXTERN int rktio_get_last_error(rktio_t *rktio);
RKTIO_EXTERN int rktio_get_last_error_kind(rktio_t *rktio);
const char *rktio_get_error_string(rktio_t *rktio, int kind, int errid);
/* The returned strings for `rktio_...error_string()` should not be
deallocated. */
RKTIO_EXTERN const char *rktio_get_last_error_string(rktio_t *rktio);
RKTIO_EXTERN const char *rktio_get_error_string(rktio_t *rktio, int kind, int errid);
/*************************************************/

View File

@ -54,3 +54,10 @@ const char *rktio_get_error_string(rktio_t *rktio, int kind, int errid)
if (s) return s;
return "???";
}
const char *rktio_get_last_error_string(rktio_t *rktio)
{
return rktio_get_error_string(rktio,
rktio_get_last_error_kind(rktio),
rktio_get_last_error(rktio));
}

View File

@ -28,6 +28,7 @@ rktio_t *rktio_init(void)
}
#endif
rktio_init_time(rktio);
rktio_init_wide(rktio);
return rktio;

View File

@ -273,6 +273,8 @@ void *rktio_envvars_to_block(rktio_t *rktio, rktio_envvars_t *envvars);
void rktio_stop_fs_change(rktio_t *rktio);
void rktio_init_time(rktio_t *rktio);
#ifdef RKTIO_SYSTEM_WINDOWS
int rktio_winsock_init(rktio_t *rktio);
void rktio_winsock_done(rktio_t *rktio);

View File

@ -36,6 +36,27 @@ typedef BOOL (WINAPI*SystemTimeToTzSpecificLocalTimeExProc_t)(void *lpTimeZoneIn
static SystemTimeToTzSpecificLocalTimeExProc_t SystemTimeToTzSpecificLocalTimeExProc;
#endif
void rktio_init_time(rktio_t *rktio)
{
#ifdef RKTIO_SYSTEM_WINDOWS
static int time_inited = 0;
if (!time_inited) {
HMODULE hm;
hm = LoadLibrary("kernel32.dll");
GetTimeZoneInformationForYearProc
= (GetTimeZoneInformationForYearProc_t)GetProcAddress(hm, "GetTimeZoneInformationForYear");
SystemTimeToTzSpecificLocalTimeExProc
= (SystemTimeToTzSpecificLocalTimeExProc_t)GetProcAddress(hm, "SystemTimeToTzSpecificLocalTimeEx");
FreeLibrary(hm);
time_inited = 1;
}
#endif
}
/*========================================================================*/
/* Time */
/*========================================================================*/
@ -124,7 +145,7 @@ intptr_t rktio_get_process_milliseconds(rktio_t *rktio)
#endif
}
intptr_t scheme_get_process_children_milliseconds(rktio_t *rktio)
intptr_t rktio_get_process_children_milliseconds(rktio_t *rktio)
{
#ifdef USER_TIME_IS_CLOCK
return 0;