X-Git-Url: http://ftp.carnet.hr/carnet-debian/scm?a=blobdiff_plain;f=apc_futex.c;fp=apc_futex.c;h=89069ff9cd131a26a53faeea1473f3e495abe353;hb=3682e0a7a26931aabca2b6e54eb08efd7dc0430b;hp=0000000000000000000000000000000000000000;hpb=575ce08215526bb71a967d69d601e77e1afbcd11;p=php5-apc.git diff --git a/apc_futex.c b/apc_futex.c new file mode 100644 index 0000000..89069ff --- /dev/null +++ b/apc_futex.c @@ -0,0 +1,116 @@ +/* + +----------------------------------------------------------------------+ + | APC | + +----------------------------------------------------------------------+ + | Copyright (c) 2006 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Brian Shire | + +----------------------------------------------------------------------+ + + */ + +/* $Id: apc_futex.c,v 3.2 2006/10/12 08:23:16 shire Exp $ */ + +/*************************************************************************** +* Futex (Fast Userspace Mutex) support for APC +* +* Futex support provides user space locking with system calls only +* for the contended cases. Some required reading for this functionality is: +* +* 'Fuss, Futexes and Furwocks: Fast Userlevel Locking in Linux' +* by Hubertus Franke, Rusty Russell, and Matthew Kirkwood +* http://www.realitydiluted.com/nptl-uclibc/docs/futex.pdf +* +* 'Futexes are Tricky' by Ulrich Drepper +* http://people.redhat.com/drepper/futex.pdf +* +* +* This implementation is optimized and designed for the i386 and x86_64 +* architectures. Other architectures may require additional design +* to efficiently and safely implement this functionality. +* +* Lock values are: +* 0 = Unlocked +* 1 = Locked without any waiting processes +* 2 = Locked with an unknown number of waiting processes +* +***************************************************************************/ + +#include "apc.h" +#include "apc_futex.h" + +#ifdef APC_FUTEX_LOCKS + + +inline int apc_futex_create() +{ + return 0; +} + +inline void apc_futex_destroy(volatile int* lock) +{ + return; +} + +void apc_futex_lock(volatile int* lock) +{ + int c; + + /* Attempt to obtain a lock if not currently locked. If the previous + * value was not 0 then we did not obtain the lock, and must wait. + * If the previous value was 1 (has no waiting processes) then we + * set the lock to 2 before blocking on the futex wait operation. + * This implementation suffers from the possible difficulty of + * efficently implementing the atomic xchg operation on some + * architectures, and could also cause unecessary wake operations by + * setting the lock to 2 when there are no additional waiters. + */ + if((c = apc_cmpxchg(lock, 0, 1)) != 0) { + if(c != 2) { + c = apc_xchg(lock, 2); + } + while(c != 0) { + apc_futex_wait(lock, 2); + c = apc_xchg(lock, 2); + } + } + +} + +/* non-blocking lock returns 1 when the lock has been obtained, 0 if it would block */ +inline zend_bool apc_futex_nonblocking_lock(volatile int* lock) +{ + return apc_cmpxchg(lock, 0, 1) == 0; +} + + +inline void apc_futex_unlock(volatile int* lock) +{ + /* set the lock to 0, if it's previous values was not 1 (no waiters) + * then perform a wake operation on one process letting it know the lock + * is available. This is an optimization to save wake calls if there + * are no waiting processes for the lock + */ + if(apc_xchg(lock,0) != 1) { + apc_futex_wake(lock, 1); + } +} + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: expandtab sw=4 ts=4 sts=4 fdm=marker + * vim<600: expandtab sw=4 ts=4 sts=4 + */