def register_time_sleep(self): if sys.platform == 'win32': Sleep = self.llexternal('Sleep', [rffi.ULONG], lltype.Void) def time_sleep_llimpl(secs): millisecs = secs * 1000.0 while millisecs > UINT_MAX: Sleep(UINT_MAX) millisecs -= UINT_MAX Sleep(rffi.cast(rffi.ULONG, int(millisecs))) else: c_select = self.llexternal('select', [rffi.INT, rffi.VOIDP, rffi.VOIDP, rffi.VOIDP, self.TIMEVALP], rffi.INT, save_err=rffi.RFFI_SAVE_ERRNO) def time_sleep_llimpl(secs): void = lltype.nullptr(rffi.VOIDP.TO) t = lltype.malloc(self.TIMEVAL, flavor='raw') try: frac = math.fmod(secs, 1.0) rffi.setintfield(t, 'c_tv_sec', int(secs)) rffi.setintfield(t, 'c_tv_usec', int(frac*1000000.0)) if rffi.cast(rffi.LONG, c_select(0, void, void, void, t)) != 0: errno = rposix.get_saved_errno() if errno != EINTR: raise OSError(errno, "Select failed") finally: lltype.free(t, flavor='raw') return extdef([float], None, llimpl=time_sleep_llimpl, export_name='ll_time.ll_time_sleep')
def register_time_time(self): # Note: time.time() is used by the framework GC during collect(), # which means that we have to be very careful about not allocating # GC memory here. This is the reason for the _nowrapper=True. # AWFUL if self.HAVE_GETTIMEOFDAY: if self.GETTIMEOFDAY_NO_TZ: c_gettimeofday = self.llexternal('gettimeofday', [self.TIMEVALP], rffi.INT, _nowrapper=True, releasegil=False) else: c_gettimeofday = self.llexternal('gettimeofday', [self.TIMEVALP, rffi.VOIDP], rffi.INT, _nowrapper=True, releasegil=False) c_ftime = None # We have gettimeofday(2), so force ftime(3) OFF. else: c_gettimeofday = None # Only look for ftime(3) if gettimeofday(2) was not found. if self.HAVE_FTIME: self.configure(CConfigForFTime) c_ftime = self.llexternal(FTIME, [lltype.Ptr(self.TIMEB)], lltype.Void, _nowrapper=True, releasegil=False) else: c_ftime = None # to not confuse the flow space c_time = self.llexternal('time', [rffi.VOIDP], rffi.TIME_T, _nowrapper=True, releasegil=False) def time_time_llimpl(): void = lltype.nullptr(rffi.VOIDP.TO) result = -1.0 if self.HAVE_GETTIMEOFDAY: t = lltype.malloc(self.TIMEVAL, flavor='raw') errcode = -1 if self.GETTIMEOFDAY_NO_TZ: errcode = c_gettimeofday(t) else: errcode = c_gettimeofday(t, void) if rffi.cast(rffi.LONG, errcode) == 0: result = decode_timeval(t) lltype.free(t, flavor='raw') if result != -1: return result else: # assume using ftime(3) t = lltype.malloc(self.TIMEB, flavor='raw') c_ftime(t) result = (float(intmask(t.c_time)) + float(intmask(t.c_millitm)) * 0.001) lltype.free(t, flavor='raw') return result return float(c_time(void)) return extdef([], float, llimpl=time_time_llimpl, export_name='ll_time.ll_time_time')
def register_time_clock(self): if sys.platform == 'win32': # hacking to avoid LARGE_INTEGER which is a union... A = lltype.FixedSizeArray(lltype.SignedLongLong, 1) QueryPerformanceCounter = self.llexternal( 'QueryPerformanceCounter', [lltype.Ptr(A)], lltype.Void, releasegil=False) QueryPerformanceFrequency = self.llexternal( 'QueryPerformanceFrequency', [lltype.Ptr(A)], rffi.INT, releasegil=False) class State(object): pass state = State() state.divisor = 0.0 state.counter_start = 0 def time_clock_llimpl(): a = lltype.malloc(A, flavor='raw') if state.divisor == 0.0: QueryPerformanceCounter(a) state.counter_start = a[0] QueryPerformanceFrequency(a) state.divisor = float(a[0]) QueryPerformanceCounter(a) diff = a[0] - state.counter_start lltype.free(a, flavor='raw') return float(diff) / state.divisor elif self.CLOCK_PROCESS_CPUTIME_ID is not None: # Linux and other POSIX systems with clock_gettime() self.configure(CConfigForClockGetTime) TIMESPEC = self.TIMESPEC CLOCK_PROCESS_CPUTIME_ID = self.CLOCK_PROCESS_CPUTIME_ID c_clock_gettime = self.llexternal('clock_gettime', [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT, releasegil=False) def time_clock_llimpl(): a = lltype.malloc(TIMESPEC, flavor='raw') c_clock_gettime(CLOCK_PROCESS_CPUTIME_ID, a) result = (float(rffi.getintfield(a, 'c_tv_sec')) + float(rffi.getintfield(a, 'c_tv_nsec')) * 0.000000001) lltype.free(a, flavor='raw') return result else: RUSAGE = self.RUSAGE RUSAGE_SELF = self.RUSAGE_SELF or 0 c_getrusage = self.llexternal('getrusage', [rffi.INT, lltype.Ptr(RUSAGE)], lltype.Void, releasegil=False) def time_clock_llimpl(): a = lltype.malloc(RUSAGE, flavor='raw') c_getrusage(RUSAGE_SELF, a) result = (decode_timeval(a.c_ru_utime) + decode_timeval(a.c_ru_stime)) lltype.free(a, flavor='raw') return result return extdef([], float, llimpl=time_clock_llimpl, export_name='ll_time.ll_time_clock')
def register_statvfs_variant(name, traits): if name != 'fstatvfs': arg_is_path = True s_arg = traits.str0 ARG1 = traits.CCHARP else: arg_is_path = False s_arg = int ARG1 = rffi.INT posix_mystatvfs = rffi.llexternal(name, [ARG1, STATVFS_STRUCT], rffi.INT, compilation_info=compilation_info, save_err=rffi.RFFI_SAVE_ERRNO) @func_renamer('os_%s_llimpl' % (name, )) def posix_statvfs_llimpl(arg): stresult = lltype.malloc(STATVFS_STRUCT.TO, flavor='raw') try: if arg_is_path: arg = traits.str2charp(arg) error = rffi.cast(rffi.LONG, posix_mystatvfs(arg, stresult)) if arg_is_path: traits.free_charp(arg) if error != 0: raise OSError(rposix.get_saved_errno(), "os_?statvfs failed") return build_statvfs_result(stresult) finally: lltype.free(stresult, flavor='raw') @func_renamer('os_%s_fake' % (name, )) def posix_fakeimpl(arg): if s_arg == traits.str0: arg = hlstr(arg) st = getattr(os, name)(arg) fields = [TYPE for fieldname, TYPE in STATVFS_FIELDS] TP = TUPLE_TYPE(fields) ll_tup = lltype.malloc(TP.TO) for i, (fieldname, TYPE) in enumerate(STATVFS_FIELDS): val = getattr(st, fieldname) rffi.setintfield(ll_tup, 'item%d' % i, int(val)) return ll_tup return extdef([s_arg], s_StatvfsResult, "ll_os.ll_os_%s" % (name, ), llimpl=posix_statvfs_llimpl, llfakeimpl=posix_fakeimpl)
def register_statvfs_variant(name, traits): if name != 'fstatvfs': arg_is_path = True s_arg = traits.str0 ARG1 = traits.CCHARP else: arg_is_path = False s_arg = int ARG1 = rffi.INT posix_mystatvfs = rffi.llexternal(name, [ARG1, STATVFS_STRUCT], rffi.INT, compilation_info=compilation_info ) @func_renamer('os_%s_llimpl' % (name,)) def posix_statvfs_llimpl(arg): stresult = lltype.malloc(STATVFS_STRUCT.TO, flavor='raw') try: if arg_is_path: arg = traits.str2charp(arg) error = rffi.cast(rffi.LONG, posix_mystatvfs(arg, stresult)) if arg_is_path: traits.free_charp(arg) if error != 0: raise OSError(rposix.get_errno(), "os_?statvfs failed") return build_statvfs_result(stresult) finally: lltype.free(stresult, flavor='raw') @func_renamer('os_%s_fake' % (name,)) def posix_fakeimpl(arg): if s_arg == traits.str0: arg = hlstr(arg) st = getattr(os, name)(arg) fields = [TYPE for fieldname, TYPE in STATVFS_FIELDS] TP = TUPLE_TYPE(fields) ll_tup = lltype.malloc(TP.TO) for i, (fieldname, TYPE) in enumerate(STATVFS_FIELDS): val = getattr(st, fieldname) rffi.setintfield(ll_tup, 'item%d' % i, int(val)) return ll_tup return extdef( [s_arg], s_StatvfsResult, "ll_os.ll_os_%s" % (name,), llimpl=posix_statvfs_llimpl, llfakeimpl=posix_fakeimpl )
def register_formatd(self): ll_strtod = self.llexternal('LL_strtod_formatd', [rffi.DOUBLE, rffi.CHAR, rffi.INT], rffi.CCHARP, sandboxsafe=True, threadsafe=False) # Like PyOS_double_to_string(), when PY_NO_SHORT_FLOAT_REPR is defined def llimpl(x, code, precision, flags): upper = False if code == 'r': code = 'g' precision = 17 elif code == 'E': code = 'e' upper = True elif code == 'F': code = 'f' upper = True elif code == 'G': code = 'g' upper = True res = ll_strtod(x, code, precision) s = rffi.charp2str(res) if flags & rfloat.DTSF_ADD_DOT_0: s = ensure_decimal_point(s, precision) # Add sign when requested if flags & rfloat.DTSF_SIGN and s[0] != '-': s = '+' + s # Convert to upper case if upper: s = s.upper() return s def oofakeimpl(x, code, precision, flags): return ootype.oostring(rfloat.formatd(x, code, precision, flags), -1) return extdef([float, lltype.Char, int, int], SomeString(can_be_None=True), 'll_strtod.ll_strtod_formatd', llimpl=llimpl, oofakeimpl=oofakeimpl, sandboxsafe=True)
def register_time_clock(self): if sys.platform == 'win32': # hacking to avoid LARGE_INTEGER which is a union... A = lltype.FixedSizeArray(lltype.SignedLongLong, 1) QueryPerformanceCounter = self.llexternal( 'QueryPerformanceCounter', [lltype.Ptr(A)], lltype.Void, threadsafe=False) QueryPerformanceFrequency = self.llexternal( 'QueryPerformanceFrequency', [lltype.Ptr(A)], rffi.INT, threadsafe=False) class State(object): pass state = State() state.divisor = 0.0 state.counter_start = 0 def time_clock_llimpl(): a = lltype.malloc(A, flavor='raw') if state.divisor == 0.0: QueryPerformanceCounter(a) state.counter_start = a[0] QueryPerformanceFrequency(a) state.divisor = float(a[0]) QueryPerformanceCounter(a) diff = a[0] - state.counter_start lltype.free(a, flavor='raw') return float(diff) / state.divisor else: RUSAGE = self.RUSAGE RUSAGE_SELF = self.RUSAGE_SELF or 0 c_getrusage = self.llexternal('getrusage', [rffi.INT, lltype.Ptr(RUSAGE)], lltype.Void, threadsafe=False) def time_clock_llimpl(): a = lltype.malloc(RUSAGE, flavor='raw') c_getrusage(RUSAGE_SELF, a) result = (decode_timeval(a.c_ru_utime) + decode_timeval(a.c_ru_stime)) lltype.free(a, flavor='raw') return result return extdef([], float, llimpl=time_clock_llimpl, export_name='ll_time.ll_time_clock')
def register_parts_to_float(self): ll_parts_to_float = self.llexternal('LL_strtod_parts_to_float', [rffi.CCHARP] * 4, rffi.DOUBLE, sandboxsafe=True, threadsafe=False) def llimpl(sign, beforept, afterpt, exponent): res = ll_parts_to_float(sign, beforept, afterpt, exponent) if res == -1 and rposix.get_errno() == 42: raise ValueError("Wrong literal for float") return res def oofakeimpl(sign, beforept, afterpt, exponent): return rfloat.parts_to_float(sign._str, beforept._str, afterpt._str, exponent._str) tp = SomeString(can_be_None=True) return extdef([tp, tp, tp, tp], float, 'll_strtod.ll_strtod_parts_to_float', llimpl=llimpl, oofakeimpl=oofakeimpl, sandboxsafe=True)
def register_stat_variant(name, traits): if name != 'fstat': arg_is_path = True s_arg = traits.str0 ARG1 = traits.CCHARP else: arg_is_path = False s_arg = int ARG1 = rffi.INT if sys.platform == 'win32': # See Win32 implementation below posix_stat_llimpl = make_win32_stat_impl(name, traits) return extdef( [s_arg], s_StatResult, traits.ll_os_name(name), llimpl=posix_stat_llimpl) if sys.platform.startswith('linux'): # because we always use _FILE_OFFSET_BITS 64 - this helps things work that are not a c compiler _functions = {'stat': 'stat64', 'fstat': 'fstat64', 'lstat': 'lstat64'} c_func_name = _functions[name] else: c_func_name = name posix_mystat = rffi.llexternal(c_func_name, [ARG1, STAT_STRUCT], rffi.INT, compilation_info=compilation_info) @func_renamer('os_%s_llimpl' % (name,)) def posix_stat_llimpl(arg): stresult = lltype.malloc(STAT_STRUCT.TO, flavor='raw') try: if arg_is_path: arg = traits.str2charp(arg) error = rffi.cast(rffi.LONG, posix_mystat(arg, stresult)) if arg_is_path: traits.free_charp(arg) if error != 0: raise OSError(rposix.get_errno(), "os_?stat failed") return build_stat_result(stresult) finally: lltype.free(stresult, flavor='raw') @func_renamer('os_%s_fake' % (name,)) def posix_fakeimpl(arg): if s_arg == traits.str0: arg = hlstr(arg) st = getattr(os, name)(arg) fields = [TYPE for fieldname, TYPE in STAT_FIELDS] TP = TUPLE_TYPE(fields) ll_tup = lltype.malloc(TP.TO) for i, (fieldname, TYPE) in enumerate(STAT_FIELDS): val = getattr(st, fieldname) if isinstance(TYPE, lltype.Number): rffi.setintfield(ll_tup, 'item%d' % i, int(val)) elif TYPE is lltype.Float: setattr(ll_tup, 'item%d' % i, float(val)) else: setattr(ll_tup, 'item%d' % i, val) return ll_tup return extdef( [s_arg], s_StatResult, "ll_os.ll_os_%s" % (name,), llimpl=posix_stat_llimpl, llfakeimpl=posix_fakeimpl)
def register_g(): x.append('g') return extdef([], int, llimpl=lambda: 21)
def register_g(): x.append('g') return extdef([], int, llimpl=lambda : 21)
def register_stat_variant(name, traits): if name != 'fstat': arg_is_path = True s_arg = traits.str0 ARG1 = traits.CCHARP else: arg_is_path = False s_arg = int ARG1 = rffi.INT if sys.platform == 'win32': # See Win32 implementation below posix_stat_llimpl = make_win32_stat_impl(name, traits) return extdef([s_arg], s_StatResult, traits.ll_os_name(name), llimpl=posix_stat_llimpl) if sys.platform.startswith('linux'): # because we always use _FILE_OFFSET_BITS 64 - this helps things work that are not a c compiler _functions = {'stat': 'stat64', 'fstat': 'fstat64', 'lstat': 'lstat64'} c_func_name = _functions[name] else: c_func_name = name posix_mystat = rffi.llexternal(c_func_name, [ARG1, STAT_STRUCT], rffi.INT, compilation_info=compilation_info, save_err=rffi.RFFI_SAVE_ERRNO) @func_renamer('os_%s_llimpl' % (name, )) def posix_stat_llimpl(arg): stresult = lltype.malloc(STAT_STRUCT.TO, flavor='raw') try: if arg_is_path: arg = traits.str2charp(arg) error = rffi.cast(rffi.LONG, posix_mystat(arg, stresult)) if arg_is_path: traits.free_charp(arg) if error != 0: raise OSError(rposix.get_saved_errno(), "os_?stat failed") return build_stat_result(stresult) finally: lltype.free(stresult, flavor='raw') @func_renamer('os_%s_fake' % (name, )) def posix_fakeimpl(arg): if s_arg == traits.str0: arg = hlstr(arg) st = getattr(os, name)(arg) fields = [TYPE for fieldname, TYPE in STAT_FIELDS] TP = TUPLE_TYPE(fields) ll_tup = lltype.malloc(TP.TO) for i, (fieldname, TYPE) in enumerate(STAT_FIELDS): val = getattr(st, fieldname) if isinstance(TYPE, lltype.Number): rffi.setintfield(ll_tup, 'item%d' % i, int(val)) elif TYPE is lltype.Float: setattr(ll_tup, 'item%d' % i, float(val)) else: setattr(ll_tup, 'item%d' % i, val) return ll_tup return extdef([s_arg], s_StatResult, "ll_os.ll_os_%s" % (name, ), llimpl=posix_stat_llimpl, llfakeimpl=posix_fakeimpl)