Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r72262:ce8c750062dc Date: 2014-06-28 10:57 +0200 http://bitbucket.org/pypy/pypy/changeset/ce8c750062dc/
Log: merge heads diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst --- a/pypy/doc/faq.rst +++ b/pypy/doc/faq.rst @@ -465,9 +465,13 @@ This is documented (here__ and here__). It needs 4 GB of RAM to run "rpython targetpypystandalone" on top of PyPy, a bit more when running -on CPython. If you have less than 4 GB it will just swap forever (or -fail if you don't have enough swap). On 32-bit, divide the numbers by -two. +on top of CPython. If you have less than 4 GB free, it will just swap +forever (or fail if you don't have enough swap). And we mean *free:* +if the machine has 4 GB *in total,* then it will swap. + +On 32-bit, divide the numbers by two. (We didn't try recently, but in +the past it was possible to compile a 32-bit version on a 2 GB Linux +machine with nothing else running: no Gnome/KDE, for example.) .. __: http://pypy.org/download.html#building-from-source .. __: https://pypy.readthedocs.org/en/latest/getting-started-python.html#translating-the-pypy-python-interpreter diff --git a/pypy/module/_socket/__init__.py b/pypy/module/_socket/__init__.py --- a/pypy/module/_socket/__init__.py +++ b/pypy/module/_socket/__init__.py @@ -6,8 +6,8 @@ } interpleveldefs = { - 'SocketType': 'interp_socket.W_RSocket', - 'socket' : 'interp_socket.W_RSocket', + 'SocketType': 'interp_socket.W_Socket', + 'socket' : 'interp_socket.W_Socket', 'error' : 'interp_socket.get_error(space, "error")', 'herror' : 'interp_socket.get_error(space, "herror")', 'gaierror' : 'interp_socket.get_error(space, "gaierror")', diff --git a/pypy/module/_socket/interp_func.py b/pypy/module/_socket/interp_func.py --- a/pypy/module/_socket/interp_func.py +++ b/pypy/module/_socket/interp_func.py @@ -1,8 +1,12 @@ -from pypy.interpreter.gateway import unwrap_spec, WrappedDefault -from pypy.module._socket.interp_socket import converted_error, W_RSocket, addr_as_object, ipaddr_from_object from rpython.rlib import rsocket from rpython.rlib.rsocket import SocketError, INVALID_SOCKET + from pypy.interpreter.error import OperationError +from pypy.interpreter.gateway import unwrap_spec, WrappedDefault +from pypy.module._socket.interp_socket import ( + converted_error, W_Socket, addr_as_object, ipaddr_from_object +) + def gethostname(space): """gethostname() -> string @@ -136,10 +140,10 @@ The remaining arguments are the same as for socket(). """ try: - sock = rsocket.fromfd(fd, family, type, proto, W_RSocket) + sock = rsocket.fromfd(fd, family, type, proto) except SocketError, e: raise converted_error(space, e) - return space.wrap(sock) + return space.wrap(W_Socket(sock)) @unwrap_spec(family=int, type=int, proto=int) def socketpair(space, family=rsocket.socketpair_default_family, @@ -153,10 +157,13 @@ AF_UNIX if defined on the platform; otherwise, the default is AF_INET. """ try: - sock1, sock2 = rsocket.socketpair(family, type, proto, W_RSocket) + sock1, sock2 = rsocket.socketpair(family, type, proto) except SocketError, e: raise converted_error(space, e) - return space.newtuple([space.wrap(sock1), space.wrap(sock2)]) + return space.newtuple([ + space.wrap(W_Socket(sock1)), + space.wrap(W_Socket(sock2)) + ]) # The following 4 functions refuse all negative numbers, like CPython 2.6. # They could also check that the argument is not too large, but CPython 2.6 diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py --- a/pypy/module/_socket/interp_socket.py +++ b/pypy/module/_socket/interp_socket.py @@ -1,14 +1,18 @@ +from rpython.rlib import rsocket +from rpython.rlib.rarithmetic import intmask +from rpython.rlib.rsocket import ( + RSocket, AF_INET, SOCK_STREAM, SocketError, SocketErrorWithErrno, + RSocketError +) +from rpython.rtyper.lltypesystem import lltype, rffi + +from pypy.interpreter import gateway from pypy.interpreter.baseobjspace import W_Root -from pypy.interpreter.typedef import TypeDef, make_weakref_descr,\ - interp_attrproperty +from pypy.interpreter.error import OperationError, oefmt from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault -from rpython.rlib.rarithmetic import intmask -from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.rlib import rsocket -from rpython.rlib.rsocket import RSocket, AF_INET, SOCK_STREAM -from rpython.rlib.rsocket import SocketError, SocketErrorWithErrno, RSocketError -from pypy.interpreter.error import OperationError, oefmt -from pypy.interpreter import gateway +from pypy.interpreter.typedef import ( + GetSetProperty, TypeDef, make_weakref_descr +) # XXX Hack to seperate rpython and pypy @@ -124,10 +128,18 @@ return addr -class W_RSocket(W_Root, RSocket): - def __del__(self): - self.clear_all_weakrefs() - RSocket.__del__(self) +class W_Socket(W_Root): + def __init__(self, sock): + self.sock = sock + + def get_type_w(self, space): + return space.wrap(self.sock.type) + + def get_proto_w(self, space): + return space.wrap(self.sock.proto) + + def get_family_w(self, space): + return space.wrap(self.sock.family) def accept_w(self, space): """accept() -> (socket object, address info) @@ -137,22 +149,22 @@ info is a pair (hostaddr, port). """ try: - fd, addr = self.accept() + fd, addr = self.sock.accept() sock = rsocket.make_socket( - fd, self.family, self.type, self.proto, W_RSocket) - return space.newtuple([space.wrap(sock), + fd, self.sock.family, self.sock.type, self.sock.proto) + return space.newtuple([space.wrap(W_Socket(sock)), addr_as_object(addr, sock.fd, space)]) - except SocketError, e: + except SocketError as e: raise converted_error(space, e) # convert an Address into an app-level object def addr_as_object(self, space, address): - return addr_as_object(address, self.fd, space) + return addr_as_object(address, self.sock.fd, space) # convert an app-level object into an Address # based on the current socket's family def addr_from_object(self, space, w_address): - return addr_from_object(self.family, space, w_address) + return addr_from_object(self.sock.family, space, w_address) def bind_w(self, space, w_addr): """bind(address) @@ -162,8 +174,8 @@ sockets the address is a tuple (ifname, proto [,pkttype [,hatype]]) """ try: - self.bind(self.addr_from_object(space, w_addr)) - except SocketError, e: + self.sock.bind(self.addr_from_object(space, w_addr)) + except SocketError as e: raise converted_error(space, e) def close_w(self, space): @@ -172,7 +184,7 @@ Close the socket. It cannot be used after this call. """ try: - self.close() + self.sock.close() except SocketError: # cpython doesn't return any errors on close pass @@ -184,8 +196,8 @@ is a pair (host, port). """ try: - self.connect(self.addr_from_object(space, w_addr)) - except SocketError, e: + self.sock.connect(self.addr_from_object(space, w_addr)) + except SocketError as e: raise converted_error(space, e) def connect_ex_w(self, space, w_addr): @@ -196,15 +208,16 @@ """ try: addr = self.addr_from_object(space, w_addr) - except SocketError, e: + except SocketError as e: raise converted_error(space, e) - error = self.connect_ex(addr) + error = self.sock.connect_ex(addr) return space.wrap(error) def dup_w(self, space): try: - return self.dup(W_RSocket) - except SocketError, e: + sock = self.sock.dup() + return W_Socket(sock) + except SocketError as e: raise converted_error(space, e) def fileno_w(self, space): @@ -212,7 +225,7 @@ Return the integer file descriptor of the socket. """ - return space.wrap(intmask(self.fd)) + return space.wrap(intmask(self.sock.fd)) def getpeername_w(self, space): """getpeername() -> address info @@ -221,9 +234,9 @@ info is a pair (hostaddr, port). """ try: - addr = self.getpeername() - return addr_as_object(addr, self.fd, space) - except SocketError, e: + addr = self.sock.getpeername() + return addr_as_object(addr, self.sock.fd, space) + except SocketError as e: raise converted_error(space, e) def getsockname_w(self, space): @@ -233,9 +246,9 @@ info is a pair (hostaddr, port). """ try: - addr = self.getsockname() - return addr_as_object(addr, self.fd, space) - except SocketError, e: + addr = self.sock.getsockname() + return addr_as_object(addr, self.sock.fd, space) + except SocketError as e: raise converted_error(space, e) @unwrap_spec(level=int, optname=int) @@ -248,11 +261,11 @@ """ if w_buflen is None: try: - return space.wrap(self.getsockopt_int(level, optname)) - except SocketError, e: + return space.wrap(self.sock.getsockopt_int(level, optname)) + except SocketError as e: raise converted_error(space, e) buflen = space.int_w(w_buflen) - return space.wrap(self.getsockopt(level, optname, buflen)) + return space.wrap(self.sock.getsockopt(level, optname, buflen)) def gettimeout_w(self, space): """gettimeout() -> timeout @@ -260,7 +273,7 @@ Returns the timeout in floating seconds associated with socket operations. A timeout of None indicates that timeouts on socket """ - timeout = self.gettimeout() + timeout = self.sock.gettimeout() if timeout < 0.0: return space.w_None return space.wrap(timeout) @@ -274,8 +287,8 @@ will allow before refusing new connections. """ try: - self.listen(backlog) - except SocketError, e: + self.sock.listen(backlog) + except SocketError as e: raise converted_error(space, e) @unwrap_spec(w_mode = WrappedDefault("r"), @@ -298,8 +311,8 @@ the remote end is closed and all data is read, return the empty string. """ try: - data = self.recv(buffersize, flags) - except SocketError, e: + data = self.sock.recv(buffersize, flags) + except SocketError as e: raise converted_error(space, e) return space.wrap(data) @@ -310,13 +323,13 @@ Like recv(buffersize, flags) but also return the sender's address info. """ try: - data, addr = self.recvfrom(buffersize, flags) + data, addr = self.sock.recvfrom(buffersize, flags) if addr: - w_addr = addr_as_object(addr, self.fd, space) + w_addr = addr_as_object(addr, self.sock.fd, space) else: w_addr = space.w_None return space.newtuple([space.wrap(data), w_addr]) - except SocketError, e: + except SocketError as e: raise converted_error(space, e) @unwrap_spec(data='bufferstr', flags=int) @@ -328,8 +341,8 @@ sent; this may be less than len(data) if the network is busy. """ try: - count = self.send(data, flags) - except SocketError, e: + count = self.sock.send(data, flags) + except SocketError as e: raise converted_error(space, e) return space.wrap(count) @@ -343,8 +356,9 @@ to tell how much data has been sent. """ try: - self.sendall(data, flags, space.getexecutioncontext().checksignals) - except SocketError, e: + self.sock.sendall( + data, flags, space.getexecutioncontext().checksignals) + except SocketError as e: raise converted_error(space, e) @unwrap_spec(data='bufferstr') @@ -364,8 +378,8 @@ w_addr = w_param3 try: addr = self.addr_from_object(space, w_addr) - count = self.sendto(data, flags, addr) - except SocketError, e: + count = self.sock.sendto(data, flags, addr) + except SocketError as e: raise converted_error(space, e) return space.wrap(count) @@ -377,7 +391,7 @@ setblocking(True) is equivalent to settimeout(None); setblocking(False) is equivalent to settimeout(0.0). """ - self.setblocking(flag) + self.sock.setblocking(flag) @unwrap_spec(level=int, optname=int) def setsockopt_w(self, space, level, optname, w_optval): @@ -391,13 +405,13 @@ except: optval = space.str_w(w_optval) try: - self.setsockopt(level, optname, optval) - except SocketError, e: + self.sock.setsockopt(level, optname, optval) + except SocketError as e: raise converted_error(space, e) return try: - self.setsockopt_int(level, optname, optval) - except SocketError, e: + self.sock.setsockopt_int(level, optname, optval) + except SocketError as e: raise converted_error(space, e) def settimeout_w(self, space, w_timeout): @@ -415,7 +429,7 @@ if timeout < 0.0: raise OperationError(space.w_ValueError, space.wrap('Timeout value out of range')) - self.settimeout(timeout) + self.sock.settimeout(timeout) @unwrap_spec(nbytes=int, flags=int) def recv_into_w(self, space, w_buffer, nbytes=0, flags=0): @@ -424,8 +438,8 @@ if nbytes == 0 or nbytes > lgt: nbytes = lgt try: - return space.wrap(self.recvinto(rwbuffer, nbytes, flags)) - except SocketError, e: + return space.wrap(self.sock.recvinto(rwbuffer, nbytes, flags)) + except SocketError as e: raise converted_error(space, e) @unwrap_spec(nbytes=int, flags=int) @@ -435,13 +449,13 @@ if nbytes == 0 or nbytes > lgt: nbytes = lgt try: - readlgt, addr = self.recvfrom_into(rwbuffer, nbytes, flags) + readlgt, addr = self.sock.recvfrom_into(rwbuffer, nbytes, flags) if addr: - w_addr = addr_as_object(addr, self.fd, space) + w_addr = addr_as_object(addr, self.sock.fd, space) else: w_addr = space.w_None return space.newtuple([space.wrap(readlgt), w_addr]) - except SocketError, e: + except SocketError as e: raise converted_error(space, e) @unwrap_spec(cmd=int) @@ -473,7 +487,7 @@ option_ptr.c_keepaliveinterval = space.uint_w(w_interval) res = _c.WSAIoctl( - self.fd, cmd, value_ptr, value_size, + self.sock.fd, cmd, value_ptr, value_size, rffi.NULL, 0, recv_ptr, rffi.NULL, rffi.NULL) if res < 0: raise converted_error(space, rsocket.last_error()) @@ -494,8 +508,8 @@ (flag == SHUT_RDWR). """ try: - self.shutdown(how) - except SocketError, e: + self.sock.shutdown(how) + except SocketError as e: raise converted_error(space, e) #------------------------------------------------------------ @@ -536,12 +550,13 @@ @unwrap_spec(family=int, type=int, proto=int) def newsocket(space, w_subtype, family=AF_INET, type=SOCK_STREAM, proto=0): - sock = space.allocate_instance(W_RSocket, w_subtype) + self = space.allocate_instance(W_Socket, w_subtype) try: - W_RSocket.__init__(sock, family, type, proto) - except SocketError, e: + sock = RSocket(family, type, proto) + except SocketError as e: raise converted_error(space, e) - return space.wrap(sock) + W_Socket.__init__(self, sock) + return space.wrap(self) descr_socket_new = interp2app(newsocket) # ____________________________________________________________ @@ -597,10 +612,10 @@ socketmethods = {} for methodname in socketmethodnames: - method = getattr(W_RSocket, methodname + '_w') + method = getattr(W_Socket, methodname + '_w') socketmethods[methodname] = interp2app(method) -W_RSocket.typedef = TypeDef("_socket.socket", +W_Socket.typedef = TypeDef("_socket.socket", __doc__ = """\ socket([family[, type[, proto]]]) -> socket object @@ -639,9 +654,9 @@ [*] not available on all platforms!""", __new__ = descr_socket_new, - __weakref__ = make_weakref_descr(W_RSocket), - type = interp_attrproperty('type', W_RSocket), - proto = interp_attrproperty('proto', W_RSocket), - family = interp_attrproperty('family', W_RSocket), + __weakref__ = make_weakref_descr(W_Socket), + type = GetSetProperty(W_Socket.get_type_w), + proto = GetSetProperty(W_Socket.get_proto_w), + family = GetSetProperty(W_Socket.get_family_w), ** socketmethods ) diff --git a/pypy/tool/gcdump.py b/pypy/tool/gcdump.py --- a/pypy/tool/gcdump.py +++ b/pypy/tool/gcdump.py @@ -43,7 +43,7 @@ def print_summary(self): items = self.summary.items() - items.sort(key=lambda(typenum, stat): stat[1]) # sort by totalsize + items.sort(key=lambda (typenum, stat): stat[1]) # sort by totalsize totalsize = 0 for typenum, stat in items: totalsize += stat[1] diff --git a/rpython/rlib/_rsocket_rffi.py b/rpython/rlib/_rsocket_rffi.py --- a/rpython/rlib/_rsocket_rffi.py +++ b/rpython/rlib/_rsocket_rffi.py @@ -493,10 +493,16 @@ getnameinfo = external('getnameinfo', [sockaddr_ptr, socklen_t, CCHARP, size_t, CCHARP, size_t, rffi.INT], rffi.INT) -htonl = external('htonl', [rffi.UINT], rffi.UINT, releasegil=False) -htons = external('htons', [rffi.USHORT], rffi.USHORT, releasegil=False) -ntohl = external('ntohl', [rffi.UINT], rffi.UINT, releasegil=False) -ntohs = external('ntohs', [rffi.USHORT], rffi.USHORT, releasegil=False) +if sys.platform.startswith("openbsd"): + htonl = external('htonl', [rffi.UINT], rffi.UINT, releasegil=False, macro=True) + htons = external('htons', [rffi.USHORT], rffi.USHORT, releasegil=False, macro=True) + ntohl = external('ntohl', [rffi.UINT], rffi.UINT, releasegil=False, macro=True) + ntohs = external('ntohs', [rffi.USHORT], rffi.USHORT, releasegil=False, macro=True) +else: + htonl = external('htonl', [rffi.UINT], rffi.UINT, releasegil=False) + htons = external('htons', [rffi.USHORT], rffi.USHORT, releasegil=False) + ntohl = external('ntohl', [rffi.UINT], rffi.UINT, releasegil=False) + ntohs = external('ntohs', [rffi.USHORT], rffi.USHORT, releasegil=False) if _POSIX: inet_aton = external('inet_aton', [CCHARP, lltype.Ptr(in_addr)], diff --git a/rpython/rlib/rsocket.py b/rpython/rlib/rsocket.py --- a/rpython/rlib/rsocket.py +++ b/rpython/rlib/rsocket.py @@ -15,17 +15,18 @@ # It's unclear if makefile() and SSL support belong here or only as # app-level code for PyPy. +from rpython.rlib import _rsocket_rffi as _c, jit, rgc from rpython.rlib.objectmodel import instantiate, keepalive_until_here -from rpython.rlib import _rsocket_rffi as _c from rpython.rlib.rarithmetic import intmask, r_uint from rpython.rlib.rthread import dummy_lock from rpython.rtyper.lltypesystem import lltype, rffi from rpython.rtyper.lltypesystem.rffi import sizeof, offsetof -INVALID_SOCKET = _c.INVALID_SOCKET -from rpython.rlib import jit + + # Usage of @jit.dont_look_inside in this file is possibly temporary # and only because some lltypes declared in _rsocket_rffi choke the # JIT's codewriter right now (notably, FixedSizeArray). +INVALID_SOCKET = _c.INVALID_SOCKET def mallocbuf(buffersize): @@ -86,6 +87,7 @@ self.addr_p = addr self.addrlen = addrlen + @rgc.must_be_light_finalizer def __del__(self): if self.addr_p: lltype.free(self.addr_p, flavor='raw', track_allocation=False) @@ -493,8 +495,8 @@ class RSocket(object): """RPython-level socket object. """ - _mixin_ = True # for interp_socket.py fd = _c.INVALID_SOCKET + def __init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, fd=_c.INVALID_SOCKET): """Create a new socket.""" @@ -509,6 +511,7 @@ self.proto = proto self.timeout = defaults.timeout + @rgc.must_be_light_finalizer def __del__(self): fd = self.fd if fd != _c.INVALID_SOCKET: diff --git a/rpython/translator/c/src/thread_gil.c b/rpython/translator/c/src/thread_gil.c --- a/rpython/translator/c/src/thread_gil.c +++ b/rpython/translator/c/src/thread_gil.c @@ -38,15 +38,14 @@ long rpy_fastgil = 1; long rpy_waiting_threads = -42; /* GIL not initialized */ -static mutex_t mutex_gil_stealer; -static mutex_t mutex_gil; +static mutex1_t mutex_gil_stealer; +static mutex2_t mutex_gil; void RPyGilAllocate(void) { assert(RPY_FASTGIL_LOCKED(rpy_fastgil)); - mutex_init(&mutex_gil_stealer); - mutex_init(&mutex_gil); - mutex_lock(&mutex_gil); + mutex1_init(&mutex_gil_stealer); + mutex2_init_locked(&mutex_gil); rpy_waiting_threads = 0; } @@ -80,14 +79,15 @@ first-in-first-out order, this will nicely give the threads a round-robin chance. */ - mutex_lock(&mutex_gil_stealer); + mutex1_lock(&mutex_gil_stealer); + mutex2_loop_start(&mutex_gil); /* We are now the stealer thread. Steals! */ while (1) { /* Sleep for one interval of time. We may be woken up earlier if 'mutex_gil' is released. */ - if (mutex_lock_timeout(&mutex_gil, 0.0001)) { /* 0.1 ms... */ + if (mutex2_lock_timeout(&mutex_gil, 0.0001)) { /* 0.1 ms... */ /* We arrive here if 'mutex_gil' was recently released and we just relocked it. */ @@ -107,7 +107,8 @@ /* Otherwise, loop back. */ } atomic_decrement(&rpy_waiting_threads); - mutex_unlock(&mutex_gil_stealer); + mutex2_loop_stop(&mutex_gil); + mutex1_unlock(&mutex_gil_stealer); RESTORE_ERRNO(); } @@ -140,7 +141,7 @@ /* Explicitly release the 'mutex_gil'. */ - mutex_unlock(&mutex_gil); + mutex2_unlock(&mutex_gil); /* Now nobody has got the GIL, because 'mutex_gil' is released (but rpy_fastgil is still locked). Call RPyGilAcquire(). It will diff --git a/rpython/translator/c/src/thread_nt.c b/rpython/translator/c/src/thread_nt.c --- a/rpython/translator/c/src/thread_nt.c +++ b/rpython/translator/c/src/thread_nt.c @@ -196,33 +196,46 @@ /* GIL code */ /************************************************************/ -typedef HANDLE mutex_t; /* a semaphore, on Windows */ +typedef HANDLE mutex2_t; /* a semaphore, on Windows */ static void gil_fatal(const char *msg) { fprintf(stderr, "Fatal error in the GIL: %s\n", msg); abort(); } -static inline void mutex_init(mutex_t *mutex) { +static inline void mutex2_init(mutex2_t *mutex) { *mutex = CreateSemaphore(NULL, 1, 1, NULL); if (*mutex == NULL) gil_fatal("CreateSemaphore failed"); } -static inline void mutex_lock(mutex_t *mutex) { +static inline void mutex2_lock(mutex2_t *mutex) { WaitForSingleObject(*mutex, INFINITE); } -static inline void mutex_unlock(mutex_t *mutex) { +static inline void mutex2_unlock(mutex2_t *mutex) { ReleaseSemaphore(*mutex, 1, NULL); } -static inline int mutex_lock_timeout(mutex_t *mutex, double delay) +static inline void mutex2_init_locked(mutex2_t *mutex) { + mutex2_init(mutex); + mutex2_lock(mutex); +} + +static inline void mutex2_loop_start(mutex2_t *mutex) { } +static inline void mutex2_loop_stop(mutex2_t *mutex) { } + +static inline int mutex2_lock_timeout(mutex2_t *mutex, double delay) { DWORD result = WaitForSingleObject(*mutex, (DWORD)(delay * 1000.0 + 0.999)); return (result != WAIT_TIMEOUT); } +#define mutex1_t mutex2_t +#define mutex1_init mutex2_init +#define mutex1_lock mutex2_lock +#define mutex1_unlock mutex2_unlock + #ifdef _M_IA64 /* On Itanium, use 'acquire' memory ordering semantics */ #define lock_test_and_set(ptr, value) InterlockedExchangeAcquire(ptr, value) diff --git a/rpython/translator/c/src/thread_pthread.c b/rpython/translator/c/src/thread_pthread.c --- a/rpython/translator/c/src/thread_pthread.c +++ b/rpython/translator/c/src/thread_pthread.c @@ -479,12 +479,20 @@ #define ASSERT_STATUS(call) \ if (call != 0) { \ - fprintf(stderr, "Fatal error: " #call "\n"); \ + perror("Fatal error: " #call); \ abort(); \ } -static inline void timespec_add(struct timespec *t, double incr) +static inline void timespec_delay(struct timespec *t, double incr) { +#ifdef CLOCK_REALTIME + clock_gettime(CLOCK_REALTIME, &t); +#else + struct timeval tv; + RPY_GETTIMEOFDAY(&tv); + t->tv_sec = tv.tv_sec; + t->tv_nsec = tv.tv_usec * 1000 + 999; +#endif /* assumes that "incr" is not too large, less than 1 second */ long nsec = t->tv_nsec + (long)(incr * 1000000000.0); if (nsec >= 1000000000) { @@ -495,27 +503,56 @@ t->tv_nsec = nsec; } -typedef pthread_mutex_t mutex_t; +typedef pthread_mutex_t mutex1_t; -static inline void mutex_init(mutex_t *mutex) { +static inline void mutex1_init(mutex1_t *mutex) { ASSERT_STATUS(pthread_mutex_init(mutex, pthread_mutexattr_default)); } -static inline void mutex_lock(mutex_t *mutex) { +static inline void mutex1_lock(mutex1_t *mutex) { ASSERT_STATUS(pthread_mutex_lock(mutex)); } -static inline void mutex_unlock(mutex_t *mutex) { +static inline void mutex1_unlock(mutex1_t *mutex) { ASSERT_STATUS(pthread_mutex_unlock(mutex)); } -static inline int mutex_lock_timeout(mutex_t *mutex, double delay) { - struct timespec t; - clock_gettime(CLOCK_REALTIME, &t); - timespec_add(&t, delay); - int error_from_timedlock = pthread_mutex_timedlock(mutex, &t); - if (error_from_timedlock == ETIMEDOUT) - return 0; - ASSERT_STATUS(error_from_timedlock); - return 1; + +typedef struct { + char locked; + pthread_mutex_t mut; + pthread_cond_t cond; +} mutex2_t; + +static inline void mutex2_init_locked(mutex2_t *mutex) { + mutex->locked = 1; + ASSERT_STATUS(pthread_mutex_init(&mutex->mut, pthread_mutexattr_default)); + ASSERT_STATUS(pthread_cond_init(&mutex->cond, pthread_condattr_default)); } +static inline void mutex2_unlock(mutex2_t *mutex) { + ASSERT_STATUS(pthread_mutex_lock(&mutex->mut)); + mutex->locked = 0; + ASSERT_STATUS(pthread_mutex_unlock(&mutex->mut)); + ASSERT_STATUS(pthread_cond_signal(&mutex->cond)); +} +static inline void mutex2_loop_start(mutex2_t *mutex) { + ASSERT_STATUS(pthread_mutex_lock(&mutex->mut)); +} +static inline void mutex2_loop_stop(mutex2_t *mutex) { + ASSERT_STATUS(pthread_mutex_unlock(&mutex->mut)); +} +static inline int mutex2_lock_timeout(mutex2_t *mutex, double delay) { + if (mutex->locked) { + struct timespec t; + timespec_delay(&t, delay); + int error_from_timedwait = pthread_cond_timedwait( + &mutex->cond, &mutex->mut, &t); + if (error_from_timedwait != ETIMEDOUT) { + ASSERT_STATUS(error_from_timedwait); + } + } + int result = !mutex->locked; + mutex->locked = 1; + return result; +} + #define lock_test_and_set(ptr, value) __sync_lock_test_and_set(ptr, value) #define atomic_increment(ptr) __sync_fetch_and_add(ptr, 1) #define atomic_decrement(ptr) __sync_fetch_and_sub(ptr, 1) diff --git a/rpython/translator/platform/posix.py b/rpython/translator/platform/posix.py --- a/rpython/translator/platform/posix.py +++ b/rpython/translator/platform/posix.py @@ -22,9 +22,11 @@ return ['-l%s' % lib for lib in libraries] def _libdirs(self, library_dirs): + assert '' not in library_dirs return ['-L%s' % ldir for ldir in library_dirs] def _includedirs(self, include_dirs): + assert '' not in include_dirs return ['-I%s' % idir for idir in include_dirs] def _linkfiles(self, link_files): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit