Ticket #346: spinlocks.diff

File spinlocks.diff, 13.9 KB (added by arnecls, 5 years ago)

GIT diff file for xcache 3.1.0

  • config.m4

    From 7e88b22bf477cb95191461bfbebb057f5709bd50 Mon Sep 17 00:00:00 2001
    From: Arne Claus <arne.claus@trivago.com>
    Date: Tue, 19 Aug 2014 13:23:03 +0200
    Subject: [PATCH] Spinlock added as an option
    
    ---
     config.m4              |  7 ++++++
     config.w32             |  9 ++++++-
     mod_cacher/xc_cacher.c | 38 +++++++++++++++++++---------
     xcache.h               |  1 +
     xcache/xc_atomic.h     | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++
     xcache/xc_spinlock.c   | 54 +++++++++++++++++++++++++++++++++++++++
     xcache/xc_spinlock.h   | 18 +++++++++++++
     7 files changed, 182 insertions(+), 13 deletions(-)
     create mode 100644 xcache/xc_atomic.h
     create mode 100644 xcache/xc_spinlock.c
     create mode 100644 xcache/xc_spinlock.h
    
    diff --git a/config.m4 b/config.m4
    index af0ce8b..535abb9 100644
    a b xc_const_string.c \ 
    3838xc_extension.c \
    3939xc_ini.c \
    4040xc_mutex.c \
     41xc_spinlock.c \
    4142xc_opcode_spec.c \
    4243xc_processor.c \
    4344xc_sandbox.c \
    done 
    7980    AC_DEFINE([HAVE_XCACHE_DPRINT], 1, [Define to enable XCache debug print functions])
    8081  fi
    8182
     83  PHP_ARG_ENABLE(xcache-spinlock, for using XCache spinlocks,
     84  [  --enable-xcache-spinlock        XCache: Use spinlocks instead of mutexes], no, no)
     85  if test "$PHP_XCACHE_SPINLOCK" != "no"; then
     86    AC_DEFINE([HAVE_XCACHE_SPINLOCK], 1, [Define to enable XCache spinlocks])
     87  fi
     88
    8289  PHP_NEW_EXTENSION(xcache, $xcache_sources, $ext_shared)
    8390  for module in $XCACHE_MODULES; do
    8491    PHP_ADD_BUILD_DIR($ext_builddir/mod_$module)
  • config.w32

    diff --git a/config.w32 b/config.w32
    index 03046b7..559177e 100644
    a b ARG_ENABLE("xcache", "XCache Extension", "no"); 
    55
    66if (PHP_XCACHE != "no") {
    77    EXTENSION("xcache", "xcache.c", null, "/I " + configure_module_dirname);
    8     // {{{ check for xcache-constant 
     8    // {{{ check for xcache-constant
    99    ARG_ENABLE("xcache-constant", "XCache: Handle new constants made by php compiler (e.g.: for __halt_compiler)", "yes");
    1010    if (PHP_XCACHE_CONSTANT != "no") {
    1111        AC_DEFINE("HAVE_XCACHE_CONSTANT", 1, "Define to enable XCache handling of compile time constants");
    xc_const_string.c \ 
    2525xc_extension.c \
    2626xc_ini.c \
    2727xc_mutex.c \
     28xc_spinlock.c \
    2829xc_opcode_spec.c \
    2930xc_processor.c \
    3031xc_sandbox.c \
    xc_cacher.c \ 
    103104        AC_DEFINE("HAVE_XCACHE_DPRINT", 1, "Define to enable XCache debug print functions");
    104105    }
    105106    // }}}
     107    // {{{ check for xcache-spinlock
     108    ARG_ENABLE("xcache-spinlock", "XCache: Use spinlocks instead of mutexes", "no");
     109    if (PHP_XCACHE_SPINLOCK != "no") {
     110        AC_DEFINE("HAVE_XCACHE_SPINLOCK", 1, "Define to enable XCache spinlocks");
     111    }
     112    // }}}
    106113    // {{{ get ccrule
    107114    var srcdir = configure_module_dirname;
    108115    // it's a bit harder to get builddir
  • mod_cacher/xc_cacher.c

    diff --git a/mod_cacher/xc_cacher.c b/mod_cacher/xc_cacher.c
    index e26e331..09c6f43 100644
    a b  
    3636#define ECALLOC_ONE(x) ECALLOC_N(x, 1)
    3737#define VAR_ENTRY_EXPIRED(pentry) ((pentry)->ttl && XG(request_time) > (pentry)->ctime + (time_t) (pentry)->ttl)
    3838#define CHECK(x, e) do { if ((x) == NULL) { zend_error(E_ERROR, "XCache: " e); goto err; } } while (0)
     39
     40#ifdef HAVE_XCACHE_SPINLOCK
     41#define MUTEX_TYPE xc_spinlock_t
     42#define MUTEX_INIT(x,p,i) xc_spinlock_init(x)
     43#define MUTEX_DESTROY(x) xc_spinlock_destroy(x)
     44#define MUTEX_SIZE() xc_spinlock_size()
     45#define LOCK(x) xc_spinlock_lock((x)->mutex)
     46#define UNLOCK(x) xc_spinlock_unlock((x)->mutex)
     47#else
     48#define MUTEX_TYPE xc_mutex_t
     49#define MUTEX_INIT(x,p,i) xc_mutex_init(x,p,i)
     50#define MUTEX_DESTROY(x) xc_mutex_destroy(x)
     51#define MUTEX_SIZE() xc_mutex_size()
    3952#define LOCK(x) xc_mutex_lock((x)->mutex)
    4053#define UNLOCK(x) xc_mutex_unlock((x)->mutex)
     54#endif
    4155
    4256#define ENTER_LOCK_EX(x) \
    4357    LOCK((x)); \
    typedef struct { /* {{{ xc_cache_t: only cache info, not in shm */ 
    100114    int cacheid;
    101115    xc_hash_t  *hcache; /* hash to cacheid */
    102116
    103     xc_mutex_t *mutex;
     117    MUTEX_TYPE *mutex;
    104118    xc_shm_t   *shm; /* which shm contains us */
    105119    xc_allocator_t *allocator;
    106120
    static int xc_resolve_path(const char *filepath, char *path_buffer, xc_resolve_p 
    939953    ALLOCA_FLAG(use_heap)
    940954
    941955#if 0
    942     if ((*filepath == '.' && 
    943          (IS_SLASH(filepath[1]) || 
     956    if ((*filepath == '.' &&
     957         (IS_SLASH(filepath[1]) ||
    944958          ((filepath[1] == '.') && IS_SLASH(filepath[2])))) ||
    945959        IS_ABSOLUTE_PATH(filepath, strlen(filepath)) ||
    946960        !path ||
    static zend_bool xc_is_absolute(const char *filepath, size_t filepath_len) /* {{ 
    10121026static int xc_stat(const char *filepath, struct stat *statbuf TSRMLS_DC) /* {{{ */
    10131027{
    10141028    if (strstr(filepath, "://") != NULL) {
    1015         php_stream_statbuf ssb; 
    1016         php_stream_wrapper *wrapper = NULL; 
    1017         char *path_for_open = NULL; 
     1029        php_stream_statbuf ssb;
     1030        php_stream_wrapper *wrapper = NULL;
     1031        char *path_for_open = NULL;
    10181032
    1019         wrapper = php_stream_locate_url_wrapper(filepath, &path_for_open, 0 TSRMLS_CC); 
     1033        wrapper = php_stream_locate_url_wrapper(filepath, &path_for_open, 0 TSRMLS_CC);
    10201034        if (wrapper && wrapper->wops->url_stat
    10211035#ifdef ZEND_ENGINE_2
    10221036         && wrapper->wops->url_stat(wrapper, path_for_open, PHP_STREAM_URL_STAT_QUIET, &ssb, NULL TSRMLS_CC) == SUCCESS
    giveupsapistat: 
    11241138            while (*(++ptr) == '.');
    11251139            if (!IS_SLASH(*ptr)) {
    11261140                return FAILURE;
    1127             }   
     1141            }
    11281142        }
    11291143
    11301144        if (statbuf && VCWD_STAT(compiler->filename, statbuf) != 0) {
    static xc_shm_t *xc_cache_destroy(xc_cache_t *caches, xc_hash_t *hcache) /* {{{ 
    26072621        if (cache) {
    26082622            /* do NOT touch cached data, do not release mutex shared inside cache */
    26092623            if (cache->mutex) {
    2610                 xc_mutex_destroy(cache->mutex);
     2624                MUTEX_DESTROY(cache->mutex);
    26112625            }
    26122626            shm = cache->shm;
    26132627            if (shm) {
    static xc_cache_t *xc_cache_init(xc_shm_t *shm, const char *allocator_name, xc_h 
    26302644    memsize = shmsize / hcache->size;
    26312645
    26322646    /* Don't let it break out of mem after ALIGNed
    2633      * This is important for 
     2647     * This is important for
    26342648     * Simply loop until it fit our need
    26352649     */
    26362650    while (ALIGN(memsize) * hcache->size > shmsize && ALIGN(memsize) != memsize) {
    static xc_cache_t *xc_cache_init(xc_shm_t *shm, const char *allocator_name, xc_h 
    26552669        if (hphp) {
    26562670            CHECK(cache->cached->phps = allocator->vtable->calloc(allocator, hphp->size, sizeof(xc_entry_data_php_t*)), "create phps OOM");
    26572671        }
    2658         CHECK(cache->mutex            = allocator->vtable->calloc(allocator, 1, xc_mutex_size()), "create lock OOM");
    2659         CHECK(cache->mutex = xc_mutex_init(cache->mutex, NULL, 1), "can't create mutex");
     2672        CHECK(cache->mutex            = allocator->vtable->calloc(allocator, 1, MUTEX_SIZE()), "create lock OOM");
     2673        CHECK(cache->mutex = MUTEX_INIT(cache->mutex, NULL, 1), "can't create mutex");
    26602674
    26612675        cache->hcache  = hcache;
    26622676        cache->hentry  = hentry;
  • xcache.h

    diff --git a/xcache.h b/xcache.h
    index b48661b..2a8d310 100644
    a b  
    2020#endif
    2121#include "xcache/xc_shm.h"
    2222#include "xcache/xc_mutex.h"
     23#include "xcache/xc_spinlock.h"
    2324#include "xcache/xc_compatibility.h"
    2425
    2526extern zend_module_entry xcache_module_entry;
  • new file xcache/xc_atomic.h

    diff --git a/xcache/xc_atomic.h b/xcache/xc_atomic.h
    new file mode 100644
    index 0000000..13df991
    - +  
     1#ifndef XC_ATOMIC_H_
     2#define XC_ATOMIC_H_
     3
     4#if _MSC_VER > 1000
     5#pragma once
     6#endif /* _MSC_VER > 1000 */
     7
     8#ifdef _MSC_VER
     9/* {{{ Microsoft compiler */
     10
     11#include <intrin.h>
     12#define XC_ATOMIC_INC(value) _InterlockedIncrement(&value)
     13#define XC_ATOMIC_DEC(value) _InterlockedDecrement(&value)
     14#define XC_ATOMIC_CAS32(value, test, set) _InterlockedCompareExchange(&value, set, test)
     15
     16#if (defined(_M_AMD64) || defined(_M_X64) || defined(_M_IX86)) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2))
     17#include <emmintrin.h>
     18#define XC_ATOMIC_SPIN() _mm_pause()
     19#else
     20#define NOGDICAPMASKS
     21#define NOVIRTUALKEYCODES
     22#define NOWINSTYLES
     23#define NOMENUS
     24#define NOICONS
     25#define NOKEYSTATES
     26#define NOSYSCOMMANDS
     27#define NORASTEROPS
     28#define NOATOM
     29#define NOCLIPBOARD
     30#define NOCOLOR
     31#define NOCTLMGR
     32#define NOGDI
     33#define NOMB
     34#define NOMEMMGR
     35#define NOMETAFILE
     36#define NOMINMAX
     37#define NOPROFILER
     38#define NOSCROLL
     39#define NOSERVICE
     40#define NOSOUND
     41#define NOCOMM
     42#define NOKANJI
     43#define NOHELP
     44#define NOMCX
     45#define WIN32_LEAN_AND_MEAN
     46#include <windows.h>
     47#define XC_ATOMIC_SPIN() MemoryBarrier()
     48#endif
     49
     50/* }}} */
     51#else
     52/* {{{ GCC/Clang */
     53
     54#define XC_ATOMIC_INC(value) __sync_add_and_fetch(&value, 1)
     55#define XC_ATOMIC_DEC(value) __sync_sub_and_fetch(&value, 1)
     56#define XC_ATOMIC_CAS32(value, test, set) __sync_val_compare_and_swap(&value, test, set)
     57
     58#ifdef __SSE2__
     59#include <emmintrin.h>
     60#define XC_ATOMIC_SPIN() _mm_pause()
     61#else
     62#define XC_ATOMIC_SPIN() __sync_synchronize()
     63#endif
     64
     65/* }}} */
     66#endif
     67
     68#endif /* XC_ATOMIC_H_ */
  • new file xcache/xc_spinlock.c

    diff --git a/xcache/xc_spinlock.c b/xcache/xc_spinlock.c
    new file mode 100644
    index 0000000..8ece5ad
    - +  
     1#include "xc_spinlock.h"
     2#include "xc_atomic.h"
     3#include <assert.h>
     4
     5#ifdef _MSC_VER
     6#define XC_THREAD_YIELD() SwitchToThread();
     7#else
     8#include <sched.h>
     9#define XC_THREAD_YIELD() sched_yield();
     10#endif
     11
     12struct _xc_spinlock_t {
     13    long state;
     14};
     15
     16static inline void xc_spinlock_yield(long spincount) /* {{{ */
     17{
     18    if ((spincount & 0x3F) == 0) {
     19        XC_THREAD_YIELD();
     20    }
     21    else {
     22        XC_ATOMIC_SPIN();
     23    }
     24}
     25/* }}} */
     26size_t xc_spinlock_size(void) /* {{{ */
     27{
     28    return sizeof(xc_spinlock_t);
     29}
     30/* }}} */
     31xc_spinlock_t *xc_spinlock_init(xc_spinlock_t *shared_spinlock) /* {{{ */
     32{
     33    assert(shared_spinlock);
     34    shared_spinlock->state = 0;
     35    return shared_spinlock;
     36}
     37/* }}} */
     38void xc_spinlock_destroy(xc_spinlock_t *spinlock) /* {{{ */
     39{
     40}
     41/* }}} */
     42void xc_spinlock_lock(xc_spinlock_t *spinlock) /* {{{ */
     43{
     44    long spincount = 0;
     45    while (!XC_ATOMIC_CAS32(spinlock->state, 0, 1)) {
     46        xc_spinlock_yield(++spincount);
     47    }
     48}
     49/* }}} */
     50void xc_spinlock_unlock(xc_spinlock_t *spinlock) /* {{{ */
     51{
     52    spinlock->state = 0;
     53}
     54/* }}} */
  • new file xcache/xc_spinlock.h

    diff --git a/xcache/xc_spinlock.h b/xcache/xc_spinlock.h
    new file mode 100644
    index 0000000..4f98d1e
    - +  
     1#ifndef XC_SPINLOCK_H_
     2#define XC_SPINLOCK_H_
     3
     4#if _MSC_VER > 1000
     5#pragma once
     6#endif /* _MSC_VER > 1000 */
     7
     8#include <stdlib.h>
     9
     10typedef struct _xc_spinlock_t xc_spinlock_t;
     11
     12size_t xc_spinlock_size(void);
     13xc_spinlock_t *xc_spinlock_init(xc_spinlock_t *shared_spinlock);
     14void xc_spinlock_destroy(xc_spinlock_t *spinlock);
     15void xc_spinlock_lock(xc_spinlock_t *spinlock);
     16void xc_spinlock_unlock(xc_spinlock_t *spinlock);
     17
     18#endif /* XC_SPINLOCK_H_ */
  • xcache/xc_atomic.h

    -- 
    1.8.4.2
    
    From fb58c98b8c3055833f82898e14afe487031ac62c Mon Sep 17 00:00:00 2001
    From: Arne Claus <arne.claus@trivago.com>
    Date: Tue, 19 Aug 2014 13:52:08 +0200
    Subject: [PATCH] modified MSC check for SSE2
    
    ---
     xcache/xc_atomic.h | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/xcache/xc_atomic.h b/xcache/xc_atomic.h
    index 13df991..c8ddd88 100644
    a b  
    1313#define XC_ATOMIC_DEC(value) _InterlockedDecrement(&value)
    1414#define XC_ATOMIC_CAS32(value, test, set) _InterlockedCompareExchange(&value, set, test)
    1515
    16 #if (defined(_M_AMD64) || defined(_M_X64) || defined(_M_IX86)) && (defined(_M_IX86_FP) && (_M_IX86_FP >= 2))
     16#if defined(_M_AMD64) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 2))
    1717#include <emmintrin.h>
    1818#define XC_ATOMIC_SPIN() _mm_pause()
    1919#else
  • xcache/xc_atomic.h

    -- 
    1.8.4.2
    
    From 1b39bee8b2bb8b1c49de86ff62f363685e133cf5 Mon Sep 17 00:00:00 2001
    From: Arne Claus <arne.claus@trivago.ocm>
    Date: Fri, 29 Aug 2014 12:08:56 +0200
    Subject: [PATCH] Fixed some windows issues
    
    ---
     xcache/xc_atomic.h   | 36 ++++++++++++++++++++++++++----------
     xcache/xc_spinlock.c |  2 +-
     2 files changed, 27 insertions(+), 11 deletions(-)
    
    diff --git a/xcache/xc_atomic.h b/xcache/xc_atomic.h
    index c8ddd88..7705d0d 100644
    a b  
    88#ifdef _MSC_VER
    99/* {{{ Microsoft compiler */
    1010
    11 #include <intrin.h>
    12 #define XC_ATOMIC_INC(value) _InterlockedIncrement(&value)
    13 #define XC_ATOMIC_DEC(value) _InterlockedDecrement(&value)
    14 #define XC_ATOMIC_CAS32(value, test, set) _InterlockedCompareExchange(&value, set, test)
    15 
    16 #if defined(_M_AMD64) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 2))
    17 #include <emmintrin.h>
    18 #define XC_ATOMIC_SPIN() _mm_pause()
    19 #else
    2011#define NOGDICAPMASKS
    2112#define NOVIRTUALKEYCODES
     13#define NOWINMESSAGES
    2214#define NOWINSTYLES
     15#define NOSYSMETRICS
    2316#define NOMENUS
    2417#define NOICONS
    2518#define NOKEYSTATES
    2619#define NOSYSCOMMANDS
    2720#define NORASTEROPS
     21#define NOSHOWWINDOW
     22#define OEMRESOURCE
    2823#define NOATOM
    2924#define NOCLIPBOARD
    3025#define NOCOLOR
    3126#define NOCTLMGR
     27#define NODRAWTEXT
    3228#define NOGDI
     29#define NOKERNEL
     30#define NOUSER
     31#define NONLS
    3332#define NOMB
    3433#define NOMEMMGR
    3534#define NOMETAFILE
    3635#define NOMINMAX
    37 #define NOPROFILER
     36#define NOMSG
     37#define NOOPENFILE
    3838#define NOSCROLL
    3939#define NOSERVICE
    4040#define NOSOUND
     41#define NOTEXTMETRIC
     42#define NOWH
     43#define NOWINOFFSETS
    4144#define NOCOMM
    4245#define NOKANJI
    4346#define NOHELP
     47#define NOPROFILER
     48#define NODEFERWINDOWPOS
    4449#define NOMCX
    4550#define WIN32_LEAN_AND_MEAN
     51
    4652#include <windows.h>
     53
     54#include <intrin.h>
     55#define XC_ATOMIC_INC(value) _InterlockedIncrement(&value)
     56#define XC_ATOMIC_DEC(value) _InterlockedDecrement(&value)
     57#define XC_ATOMIC_CAS32(value, test, set) _InterlockedCompareExchange(&value, set, test)
     58
     59#if defined(_M_AMD64) || defined(_M_X64) || (defined(_M_IX86_FP) && (_M_IX86_FP >= 2))
     60#include <emmintrin.h>
     61#define XC_ATOMIC_SPIN() _mm_pause()
     62#else
    4763#define XC_ATOMIC_SPIN() MemoryBarrier()
    4864#endif
    4965
  • xcache/xc_spinlock.c

    diff --git a/xcache/xc_spinlock.c b/xcache/xc_spinlock.c
    index 8ece5ad..7d5e598 100644
    a b struct _xc_spinlock_t { 
    1313    long state;
    1414};
    1515
    16 static inline void xc_spinlock_yield(long spincount) /* {{{ */
     16static __inline void xc_spinlock_yield(long spincount) /* {{{ */
    1717{
    1818    if ((spincount & 0x3F) == 0) {
    1919        XC_THREAD_YIELD();