Commit 573d550b authored by Mark Peek's avatar Mark Peek

First attempt at removing aplib dependencies

parent e18e8a59
# Build directory
build/
# Generated and compiled files
coro/_coro.[ch]
coro/oserrors.[ch]
coro/clocks/tsc_time.c
*.pyc
*.so
......@@ -2,12 +2,8 @@ Coro runs on FreeBSD, Linux and MacOS X on i386 and amd64 architectures.
In order to build, it requires:
- cython (/usr/ports/lang/cython on FreeBSD or your package manager of choice on linux).
- aplib from the IronPort github area at the same base directory as shrapnel
Since aplib is both a build and runtime requirement, make sure that is
installed first.
Then build and install shrapnel:
To build and install shrapnel:
$ python setup.py build
# python setup.py install
......@@ -90,13 +90,13 @@ is allowed to do this. The default is 4. The default may be changed
Time
====
Shrapnel uses the `aplib.tsc_time` module for handling time. It uses the TSC
Shrapnel uses the `tsc_time` module for handling time. It uses the TSC
value for a stable and high-resolution unit of time. See that module's
documentation for more detail.
A thread is always created when you start the event loop that will
resynchronize the TSC relationship to accomodate any clock drift (see
`tick_updater` and `aplib.tsc_time.update_time_relation`).
`tick_updater` and `tsc_time.update_time_relation`).
Exception Notifier
==================
......@@ -132,7 +132,7 @@ from coro._coro import *
from coro._coro import _yield
from coro import signal_handler
from coro import optional
from aplib import tb
from coro import tb
import signal
import sys
......@@ -248,7 +248,7 @@ def tick_updater():
global tick_update_interval
while 1:
sleep_relative(tick_update_interval)
aplib.tsc_time.update_time_relation()
tsc_time.update_time_relation()
# ============================================================================
# waitpid
......@@ -382,32 +382,32 @@ def new (fun, *args, **kwargs):
# ============================================================================
# time backwards compatibility
# ============================================================================
import aplib.tsc_time
import coro.clocks.tsc_time as tsc_time
ticks_per_sec = aplib.tsc_time.ticks_per_sec
ticks_per_usec = aplib.tsc_time.ticks_per_usec
ticks_per_sec = tsc_time.ticks_per_sec
ticks_per_usec = tsc_time.ticks_per_usec
microseconds = 1000000
absolute_time_to_ticks = aplib.tsc_time.usec_to_ticks
ticks_to_absolute_time = aplib.tsc_time.ticks_to_usec
absolute_time_to_ticks_safe = aplib.tsc_time.usec_to_ticks_safe
ticks_to_absolute_time_safe = aplib.tsc_time.ticks_to_usec_safe
absolute_secs_to_ticks = aplib.tsc_time.sec_to_ticks
ticks_to_absolute_secs = aplib.tsc_time.ticks_to_sec
get_now = aplib.tsc_time.rdtsc
update_time_relation = aplib.tsc_time.update_time_relation
absolute_time_to_ticks = tsc_time.usec_to_ticks
ticks_to_absolute_time = tsc_time.ticks_to_usec
absolute_time_to_ticks_safe = tsc_time.usec_to_ticks_safe
ticks_to_absolute_time_safe = tsc_time.ticks_to_usec_safe
absolute_secs_to_ticks = tsc_time.sec_to_ticks
ticks_to_absolute_secs = tsc_time.ticks_to_sec
get_now = tsc_time.rdtsc
update_time_relation = tsc_time.update_time_relation
def get_usec():
"""This is for backwards compatibility and should not be used."""
return aplib.tsc_time.ticks_to_usec(get_now())
return tsc_time.ticks_to_usec(get_now())
def ctime_ticks(t):
"""This is for backwards compatibility and should not be used."""
return aplib.tsc_time.TSC_from_ticks(t).ctime()
return tsc_time.TSC_from_ticks(t).ctime()
def ctime_usec(u):
"""This is for backwards compatibility and should not be used."""
return aplib.tsc_time.TSC_from_posix_usec(u).ctime()
return tsc_time.TSC_from_posix_usec(u).ctime()
now = get_now()
now_usec = get_usec()
......@@ -474,7 +474,7 @@ def event_loop (timeout=30):
"""
global event_loop_is_running, with_timeout, sleep_relative
# replace time.time with our tsc-based version
time.time, time.original_time = aplib.tsc_time.now_raw_posix_fsec, time.time
time.time, time.original_time = tsc_time.now_raw_posix_fsec, time.time
with_timeout = _original_with_timeout
sleep_relative = _original_sleep_relative
if install_signal_handlers:
......
......@@ -66,9 +66,8 @@ include "python.pxi"
# Note that this cimports libc.
include "pyrex_helpers.pyx"
include "tsc_time_include.pyx"
# Ugh, Pyrex doesn't do "import aplib.tsc_time as tsc_time_module" the same as
# Python does. It sets tsc_time_module to `aplib`.
from aplib import tsc_time as tsc_time_module
from coro.clocks import tsc_time as tsc_time_module
cdef extern from "stdlib.h":
IF UNAME_SYSNAME == "Linux":
......@@ -778,7 +777,7 @@ def set_exception_notifier (new_func):
# every time through __resume/__yield().
cdef extern void _wrap0 (void *)
from aplib import tb
from coro import tb
cdef public void _wrap1 "_wrap1" (coro co):
try:
......
# Copyright (c) 2002-2011 IronPort Systems and Cisco Systems
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# Pyrex definition file for tsc_time module objects.
# Work around Pyrex's poor recursive import/include support.
cimport libc as _libc
cdef class Time:
cdef readonly _libc.int64_t tsc
cdef c_ctime(self)
cdef c_localtime(self)
cdef c_gmtime(self)
cdef c_mkstr_local(self, char * format)
cdef c_mkstr_utc(self, char * format)
cdef class TSC(Time):
pass
cdef class Posix(Time):
pass
cdef class uPosix(Time):
pass
cdef class fPosix(Time):
pass
This diff is collapsed.
# Copyright (c) 2002-2011 IronPort Systems and Cisco Systems
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
"""OSError mapping.
This module maps OSErrors to specific, catchable exceptions. For example, an
OSError with an errno of ENOENT will be raised as the ENOENT exception. All
exceptions derive from OSError, so it is compatible with regular OSError
handling.
"""
include "python.pxi"
import errno
import new
import sys
cimport libc
err_map = {}
def map_exception(e):
"""Raise an errno-specific exception.
:Parameters:
- `e`: The OSError instance.
"""
# Ignoring e.filename since it seems less than useful to me.
try:
raise err_map[e.errno](e.errno, e.strerror)
except KeyError:
raise e
def raise_oserror(int error_number):
"""Raise an OSError exception by errno.
:Parameters:
- `error_number`: The errno value to raise.
"""
map_exception(OSError(error_number, libc.strerror(error_number)))
__m = sys.modules['coro.oserrors']
__g = __m.__dict__
for errcode, errname in errno.errorcode.items():
# Not sure why __module__ is not getting set properly. Python looks at
# globals() to fine __name__ to set the value, and it appears to be
# set to __main__ for some odd reason.
c = new.classobj(errname, (OSError,), {'__module__': 'coro.oserrors'})
err_map[errcode] = c
__g[errname] = c
......@@ -31,7 +31,6 @@ __socket_version__ = "$Id: //prod/main/ap/shrapnel/coro/socket.pyx#57 $"
import socket as __socketmodule
from aplib.net.ip import is_ipv6, is_ipv4
IF UNAME_SYSNAME == "Linux":
cdef extern from "stdint.h":
ctypedef unsigned char uint8_t
......@@ -1542,28 +1541,6 @@ def make_socket (int domain, int stype):
"""
return sock (domain, stype)
def make_socket_for_ip(ip, stype=SOCK_STREAM):
"""Create a socket object with the correct address family for ip.
:Parameters:
- `ip`: An IP address as a string
- `stype`: The socket type (see `SOCK`).
:Return:
Returns a socket object.
:Exceptions:
- `OSError`: OS-level error.
- `ValueError`: Invalid IP address.
"""
if is_ipv4(ip):
return make_socket(AF_INET, stype)
elif is_ipv6(ip):
return make_socket(AF_INET6, stype)
else:
raise ValueError('Invalid IP address')
def has_ipv6():
"""Whether or not this system can create an IPv6 socket.
......
# Copyright (c) 2002-2011 IronPort Systems and Cisco Systems
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
"""Compact stack trace functions.
This module provides some functions to get a stack trace string.
These stack traces are much more compact than the ones generated by the
traceback module.
"""
import os
import sys
def _get_module_name(n):
try:
path, filename = os.path.split(n)
path, directory = os.path.split(path)
#name, ext = os.path.splitext(filename)
if directory:
return '/'.join((directory, filename))
else:
return filename
except:
return '???'
def stack_string(f=None):
"""Return a compact string representing the current call stack.
:Parameters:
- `f`: Frame object. If not specified, will use the current call
position.
:Return:
Returns a string of the current stack trace.
"""
if f is None:
try:
raise ZeroDivisionError
except ZeroDivisionError:
f = sys.exc_info()[2].tb_frame.f_back
stack = []
while f is not None:
stack.append(
_get_module_name(f.f_code.co_filename) + ' ' +
f.f_code.co_name + '|' +
str(f.f_lineno)
)
f = f.f_back
return '[' + ('] ['.join(stack))+ ']'
def traceback_string(t=None, v=None, tb=None):
"""Returns a compact string representing the current exception.
If an exception is not provided as an argument, then it will get the
current exception from `sys.exc_info`.
:Parameters:
- `t`: Exception type.
- `v`: Exception value.
- `tb`: Traceback object.
:Return:
Returns a string of the current exception and stack trace.
"""
if t is None:
t,v,tb = sys.exc_info()
tbinfo = []
if tb is None:
# this should never happen, but then again, lots of things
# should never happen but do
return 'traceback is None!!!'
while tb is not None:
tbinfo.append (
_get_module_name (tb.tb_frame.f_code.co_filename) + ' ' +
tb.tb_frame.f_code.co_name + '|' +
str(tb.tb_lineno)
)
tb = tb.tb_next
# just to be safe
del tb
first = tbinfo[-1]
info = '[' + ('] ['.join (tbinfo)) + ']'
return repr(((first), str(t), str(v), info))
......@@ -47,7 +47,7 @@ __version__ = '$Revision: #1 $'
import coro
import signal
import sys
from aplib import tb
from coro import tb
import unittest
exc_str_list = []
......
/*
Copyright (c) 2002-2011 IronPort Systems and Cisco Systems
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
/*
Helper functions for Pyrex.
These will be (hopefully) inlined into your code. Say:
include "pyrex_helpers.pyx"
in your Pyrex file to include these functions.
*/
#ifndef _PYREX_HELPERS_H_
#define _PYREX_HELPERS_H_
#include "Python.h"
#define PyINLINE_FUNC(RTYPE) static __attribute__ ((no_instrument_function)) inline RTYPE
/* Support varargs support.
If there is a C type that you need that is not here, feel free to add it.
Someday Pyrex may have native support for this.
*/
#define va_int(ap) va_arg(ap, int)
#define va_charptr(ap) va_arg(ap, char *)
/* Convenience/performance. */
#define IMAX(a,b) ((a) > (b) ? (a) : (b))
#define IMIN(a,b) ((a) < (b) ? (a) : (b))
/* Converting Python builtins to direct calls. */
#define callable(o) PyCallable_Check(o)
#define type(o) PyObject_Type(o)
/* Abstract functions. */
PyINLINE_FUNC(PyObject *)
PySequence_Fast_GET_ITEM_SAFE (PyObject * o, int i)
{
PyObject * x = PySequence_Fast_GET_ITEM(o, i);
Py_INCREF(x);
return x;
}
PyINLINE_FUNC(int)
cmp (PyObject * o1, PyObject * o2)
{
int result;
if(PyObject_Cmp(o1, o2, &result)) {
return -1;
} else {
return result;
}
}
/* List functions. */
PyINLINE_FUNC(PyObject *)
PyList_GET_ITEM_SAFE (PyObject * l, int i)
{
PyObject * x = PyList_GET_ITEM (l, i);
Py_INCREF (x);
return x;
}
PyINLINE_FUNC(void)
PyList_SET_ITEM_SAFE (PyObject * l, int i, PyObject * v)
{
PyList_SET_ITEM (l, i, v);
Py_INCREF (v);
}
PyINLINE_FUNC(PyObject *)
PyList_GetItem_SAFE (PyObject * l, int i)
{
PyObject * x = PyList_GetItem (l, i);
Py_INCREF (x);
return x;
}
PyINLINE_FUNC(void)
PyList_SetItem_SAFE (PyObject * l, int i, PyObject * v)
{
PyList_SetItem (l, i, v);
Py_INCREF (v);
}
/* Tuple functions. */
PyINLINE_FUNC(PyObject *)
PyTuple_GET_ITEM_SAFE (PyObject * l, int i)
{
PyObject * x = PyTuple_GET_ITEM (l, i);
Py_INCREF (x);
return x;
}
PyINLINE_FUNC(void)
PyTuple_SET_ITEM_SAFE (PyObject * l, int i, PyObject * v)
{
PyTuple_SET_ITEM (l, i, v);
Py_INCREF (v);
}
PyINLINE_FUNC(PyObject *)
PyTuple_GetItem_SAFE (PyObject * l, int i)
{
PyObject * x = PyTuple_GetItem (l, i);
Py_INCREF (x);
return x;
}
PyINLINE_FUNC(void)
PyTuple_SetItem_SAFE (PyObject * l, int i, PyObject * v)
{
PyTuple_SetItem (l, i, v);
Py_INCREF (v);
}
/* Dict functions. */
/*
Note, you *must* set ``instead`` to a real Python object, you cannot set it
to NULL. Suggest using None.
*/
PyINLINE_FUNC(PyObject *)
PyDict_GET_ITEM_SAFE (PyObject * d, PyObject * k, PyObject * instead)
{
PyObject * r = PyDict_GetItem (d, k);
if (r == NULL) {
r = instead;
}
Py_INCREF (r);
return r;
}
/* Memory functions. */
/*
These functions are "safe" in that they set MemoryError if it fails.
Note that "free" doesn't do anything special, it's just here to maintain a
consistent naming scheme.
*/
PyINLINE_FUNC(void *)
Pyrex_Malloc_SAFE(size_t size)
{
void * r;
r = PyMem_Malloc(size);
if (r == NULL) {
PyErr_NoMemory();
return NULL;
} else {
return r;
}
}
PyINLINE_FUNC(void *)
Pyrex_Realloc_SAFE(void * ptr, size_t size)
{
void * r;
r = PyMem_Realloc(ptr, size);
if (r == NULL) {
PyErr_NoMemory();
return NULL;
} else {
return r;
}
}
PyINLINE_FUNC(void)
Pyrex_Free_SAFE(void * ptr)
{
PyMem_Free(ptr);
}
/* Number functions. */
PyINLINE_FUNC(PyObject *)
minimal_ulonglong(unsigned long long value)
{
if (value > PyInt_GetMax()) {
return PyLong_FromUnsignedLongLong(value);
} else {
return PyInt_FromLong(value);
}
}
PyINLINE_FUNC(PyObject *)
minimal_long_long(long long value)
{
if (value > PyInt_GetMax() || value < -PyInt_GetMax()-1) {
return PyLong_FromLongLong(value);
} else {
return PyInt_FromLong(value);
}
}
PyINLINE_FUNC(PyObject *)
minimal_ulong(unsigned long value)
{
if (value > PyInt_GetMax()) {
return PyLong_FromUnsignedLong(value);
} else {
return PyInt_FromLong(value);
}
}
#endif
/*
Copyright (c) 2002-2011 IronPort Systems and Cisco Systems
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef _RDTSC_H_
#define _RDTSC_H_
/*
rdtsc - ReaD TimeStamp Counter
The cycle counter in the Pentium series of processors is incremented
once for every clock cycle. It starts out as 0 on system boot.
It is a 64-bit number, and thus will wrap over in 292 years on a
2 gigahertz processor. It should keep counting unless the system
goes into deep sleep mode.
There is still some uncertainty about the P4 Xeon processor which
has the ability to lower its clock cycle when a temperature
threshold is met. Does this also change the frequency of the TSC?
FYI, the control registers on the Pentium can be configured to
restrict RDTSC to privileged level 0.
The RDTSC instruction is generally not synchronized. Thus, with
out of order execution, it is possible for it to run ahead of
other instructions that came before it. This is mainly only important
if you are trying to do exact profiling of instruction cycles.
I for the life of me can't find the number of actual cycles it takes
to read the counter for the Pentium 4. It's 11 cycles on the AMD
Athlon.
FreeBSD does not use the TSC for two apparent reasons: It is difficult
to synchronize on an SMP machine, and it is difficult to account for
time on a machine with APM enabled. Neither of these should affect us.
Some notes about FreeBSD and frequency counters:
- The TSC frequency can be found via sysctl as machdep.tsc_freq.
- FreeBSD will not bother to compute tsc_freq if you are building an SMP
kernel, or you have APM enabled.
- By default, FreeBSD will assume the i8254 timer frequency is 1193182
- If you compile with CLK_USE_I8254_CALIBRATION, it will try to determine
what the actual i8254 frequency is using the mc146818A chip.
- If you compile with CLK_USE_TSC_CALIBRATION, it will try to determine
what the actual TSC frequency is using the mc146818A chip. Otherwise
it will use a less acurate approximation using the i8254 chip.
- If you compile with CLK_CALIBRATION_LOOP, then during bootup it will
recompute the clock frequencies over and over again until you press
a key on the console (debugging to see if the clock calibration
routines are correct?).
*/
static inline
uint64_t
rdtsc(void)
{
uint32_t a, d;
asm volatile ("rdtsc" : "=a"(a), "=d"(d));
return (((uint64_t) d << 32) | a);
}
#endif /* _RDTSC_H_ */
/*
Copyright (c) 2002-2011 IronPort Systems and Cisco Systems
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
This header file provides a method to access the C functions from the tsc_time
module directly.
To use, include this header file in your C extension module. In the
initmodulename function, be sure to call init_tsc_time_pointers().
The raw conversion functions can be called directly like this:
int64_t t = usec_to_ticks(somevalue);
The constructors can be called like this:
TSC * t = now_tsc();
printf("%llu\n", t.tsc);
The structures are provided so that you can access the "tsc" value directly.
The type objects are also available if you need to do type comparisons, but I
suspect this won't be necessary.
Note that there is a small memory leak because there is no finalizer here (when
Python exits).
*/
#ifndef _TSC_TIME_H_
#define _TSC_TIME_H_
#include "Python.h"
#include <inttypes.h>
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
Pointers to the raw low-level conversion functions.
*/
static int64_t (*usec_to_ticks) (int64_t);
static int64_t (*ticks_to_usec) (int64_t);
static int64_t (*sec_to_ticks) (int64_t);
static int64_t (*ticks_to_sec) (int64_t);
static double (*ticks_to_fsec) (int64_t);
static int64_t (*fsec_to_ticks) (double);
static void (*update_time_relation) (void);
static int64_t (*rdtsc) (void);
typedef struct Time {
PyObject_HEAD
int64_t tsc;
} Time;
typedef struct TSC {
PyObject_HEAD
int64_t tsc;
} TSC;
typedef struct Posix {
PyObject_HEAD
int64_t tsc;
} Posix;
typedef struct uPosix {
PyObject_HEAD
int64_t tsc;
} uPosix;
typedef struct fPosix {
PyObject_HEAD
int64_t tsc;
} fPosix;
static PyObject * Time_Type = NULL;
static PyObject * TSC_Type = NULL;
static PyObject * Posix_Type = NULL;
static PyObject * uPosix_Type = NULL;
static PyObject * fPosix_Type = NULL;
/*
Pointers to construction functions.
*/
static TSC * (*now_tsc)(void);
static Posix * (*now_posix_sec)(void);
static uPosix * (*now_posix_usec)(void);
static fPosix * (*now_posix_fsec)(void);
/*
Initialize pointers to the tsc_time module.
Returns 0 on success, -1 on failure (with python exception set).
*/
int
init_tsc_time_pointers(void)
{
PyObject * m = NULL;
PyObject * c_obj = NULL;
void ** c_ptr;
if (Time_Type != NULL) {
// Already initialized.
return 0;
}
m = PyImport_ImportModule("coro.clocks.tsc_time");
if (m == NULL) {
goto fail;
}
c_obj = PyObject_GetAttrString(m, "_extern_pointers");
if (c_obj == NULL) {
goto fail;
}
c_ptr = (void **) PyCObject_AsVoidPtr(c_obj);
if (c_ptr == NULL) {
goto fail;
}
usec_to_ticks = (int64_t (*)(int64_t)) c_ptr[0];
ticks_to_usec = (int64_t (*)(int64_t)) c_ptr[1];
sec_to_ticks = (int64_t (*)(int64_t)) c_ptr[2];
ticks_to_sec = (int64_t (*)(int64_t)) c_ptr[3];
ticks_to_fsec = (double (*)(int64_t)) c_ptr[4];
fsec_to_ticks = (int64_t (*)(double)) c_ptr[5];
update_time_relation = (void (*)(void)) c_ptr[6];
now_tsc = (TSC * (*)(void)) c_ptr[7];
now_posix_sec = (Posix * (*)(void)) c_ptr[8];
now_posix_usec = (uPosix * (*)(void)) c_ptr[9];
now_posix_fsec = (fPosix * (*)(void)) c_ptr[10];
rdtsc = (int64_t (*)(void)) c_ptr[11];
Time_Type = PyObject_GetAttrString(m, "Time");
TSC_Type = PyObject_GetAttrString(m, "TSC");
Posix_Type = PyObject_GetAttrString(m, "Posix");
uPosix_Type = PyObject_GetAttrString(m, "uPosix");
fPosix_Type = PyObject_GetAttrString(m, "fPosix");
Py_DECREF(m);
Py_DECREF(c_obj);
return 0;
fail:
Py_XDECREF(m);
Py_XDECREF(c_obj);
return -1;
}
#ifdef __cplusplus
} /* extern C */
#endif
#endif /* _TSC_TIME_H_ */
This directory contains a collection of generic Pyrex include files.
Do not put any pyrex modules in here.
This diff is collapsed.
# Copyright (c) 2002-2011 IronPort Systems and Cisco Systems
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# Pyrex interface file for inline helpers.
# Use the "include" statement to include these functions.
# You must include "python.pxi" before this file.
cdef object oserrors
from coro import oserrors
cimport libc
cdef raise_oserror():
oserrors.map_exception(OSError(libc.errno, libc.strerror(libc.errno)))
cdef raise_oserror_with_errno(int e):
oserrors.map_exception(OSError(e, libc.strerror(e)))
cdef object __builtin__
import __builtin__
cdef object bool
bool = __builtin__.bool
cdef extern from "pyrex_helpers.h":
int va_int(libc.va_list)
char * va_charptr(libc.va_list)
object PySequence_Fast_GET_ITEM_SAFE (object, int)
object PyList_GET_ITEM_SAFE (object, int)
void PyList_SET_ITEM_SAFE (object, int, object)
object PyList_GetItem_SAFE (object, int)
void PyList_SetItem_SAFE (object, int, object)
object PyTuple_GET_ITEM_SAFE (object, int)
void PyTuple_SET_ITEM_SAFE (object, int, object)
object PyTuple_GetItem_SAFE (object, int)
void PyTuple_SetItem_SAFE (object, int, object)
object PyDict_GET_ITEM_SAFE (object, object, object)
void * Pyrex_Malloc_SAFE (libc.size_t) except NULL
void * Pyrex_Realloc_SAFE (void *, libc.size_t) except NULL
void Pyrex_Free_SAFE (void *)
object minimal_ulonglong (unsigned long long)
object minimal_long_long (long long)
object minimal_ulong (unsigned long)
int callable (object) # Cannot fail.
int cmp (object, object) except? -1
object type (object)
int IMAX (int, int)
int IMIN (int, int)
This diff is collapsed.
# Copyright (c) 2002-2011 IronPort Systems and Cisco Systems
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# This include file makes it possible to directly access the C functions from
# the tsc_time module. To use it, you need to put this at the top of your
# Pyrex file:
#
# cimport libc
# include "python.pxi"
# include "tsc_time_include.pyx"
#
# This will also implicitly cimport the tsc_time module so that you can have
# direct access to the type objects. This allows you to do something like this:
#
# cdef tsc_time.TSC t
# t = now_tsc()
# print t.tsc
#
# This will allow direct C access to the member variables of the Time objects.
cimport coro.clocks.tsc_time as tsc_time
cdef extern from "tsc_time.h":
# Raw conversion functions.
libc.int64_t c_usec_to_ticks "usec_to_ticks" (libc.int64_t)
libc.int64_t c_ticks_to_usec "ticks_to_usec" (libc.int64_t)
libc.int64_t c_sec_to_ticks "sec_to_ticks" (libc.int64_t)
libc.int64_t c_ticks_to_sec "ticks_to_sec" (libc.int64_t)
double c_ticks_to_fsec "ticks_to_fsec" (libc.int64_t)
libc.int64_t c_fsec_to_ticks "fsec_to_ticks" (double)
void c_update_time_relation "update_time_relation" ()
libc.int64_t c_rdtsc "rdtsc" ()
# Constructors.
tsc_time.TSC now_tsc()
tsc_time.Posix now_posix_sec()
tsc_time.uPosix now_posix_usec()
tsc_time.fPosix now_posix_fsec()
int init_tsc_time_pointers() except -1
init_tsc_time_pointers()
......@@ -11,10 +11,7 @@ from Cython.Distutils.extension import Extension
import glob
import os
if os.getenv('IPROOT'):
include_dir = os.path.join( os.getenv('IPROOT'), 'ap', 'aplib')
else:
include_dir = os.path.join( os.getcwd(), '..', 'aplib')
include_dir = os.getcwd()
def newer(x, y):
x_mtime = os.path.getmtime(x)
......@@ -65,13 +62,32 @@ setup (
os.path.join(include_dir, 'pyrex', 'libc.pxd'),
]
),
pyrex_include_dirs=[os.path.join(include_dir, 'pyrex')],
pyrex_include_dirs=[
os.path.join(include_dir, '.'),
os.path.join(include_dir, 'pyrex'),
],
#include_dirs=[os.path.join(include_dir, 'pyrex')],
include_dirs=[os.path.join(include_dir, 'include')],
include_dirs=[
os.path.join(include_dir, '.'),
os.path.join(include_dir, 'include'),
],
#pyrex_compile_time_env={'COMPILE_LIO': check_lio(),
# 'CORO_DEBUG': True,
# },
),
Extension(
'coro.oserrors',
['coro/oserrors.pyx', ],
),
Extension(
'coro.clocks.tsc_time',
['coro/clocks/tsc_time.pyx', ],
pyrex_include_dirs=[os.path.join(include_dir, 'pyrex')],
include_dirs=[
os.path.join(include_dir, '.'),
os.path.join(include_dir, 'include'),
],
),
],
#packages=find_packages(),
packages=['coro'],
......
......@@ -4,7 +4,7 @@
"""
from aplib import oserrors
from coro import oserrors
import coro
import coro_unittest
import os
......
......@@ -6,7 +6,7 @@ import coro
import coro_unittest
import os
import unittest
from aplib import oserrors
from coro import oserrors
class ForceSend(coro.Interrupted):
pass
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment