reconstruct shm/allocator
git-svn-id: svn://svn.lighttpd.net/xcache/trunk@148 c26eb9a1-5813-0410-bd6c-c2e55f420ca71.1
parent
a29d074126
commit
42efedb793
|
@ -31,8 +31,8 @@ processor.lo: $(XCACHE_PROC_C) $(XCACHE_PROC_H) $(srcdir)/processor.c
|
|||
$(builddir)/disassembler.lo: $(XCACHE_PROC_H) $(srcdir)/processor.c
|
||||
disassembler.lo: $(XCACHE_PROC_H) $(srcdir)/processor.c
|
||||
|
||||
$(builddir)/xcache.lo: $(XCACHE_PROC_H) $(srcdir)/myshm.h $(srcdir)/stack.h $(srcdir)/xcache_globals.h $(srcdir)/xcache.c $(srcdir)/foreachcoresig.h
|
||||
xcache.lo: $(XCACHE_PROC_H) $(srcdir)/myshm.h $(srcdir)/stack.h $(srcdir)/xcache_globals.h $(srcdir)/xcache.c $(srcdir)/foreachcoresig.h
|
||||
$(builddir)/xcache.lo: $(XCACHE_PROC_H) $(srcdir)/xc_shm.h $(srcdir)/stack.h $(srcdir)/xcache_globals.h $(srcdir)/xcache.c $(srcdir)/foreachcoresig.h
|
||||
xcache.lo: $(XCACHE_PROC_H) $(srcdir)/xc_shm.h $(srcdir)/stack.h $(srcdir)/xcache_globals.h $(srcdir)/xcache.c $(srcdir)/foreachcoresig.h
|
||||
|
||||
xcachesvnclean: clean
|
||||
cat $(srcdir)/.cvsignore | grep -v Makefile | xargs rm -f
|
||||
|
|
|
@ -27,6 +27,8 @@ if test "$PHP_XCACHE" != "no"; then
|
|||
xcache.c \
|
||||
mmap.c \
|
||||
mem.c \
|
||||
xc_malloc.c \
|
||||
xc_shm.c \
|
||||
const_string.c \
|
||||
opcode_spec.c \
|
||||
stack.c \
|
||||
|
|
|
@ -15,6 +15,8 @@ if (PHP_XCACHE != "no") {
|
|||
xcache.c \
|
||||
mmap.c \
|
||||
mem.c \
|
||||
xc_malloc.c \
|
||||
xc_shm.c \
|
||||
const_string.c \
|
||||
opcode_spec.c \
|
||||
stack.c \
|
||||
|
|
80
mem.c
80
mem.c
|
@ -8,7 +8,9 @@
|
|||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "mem.h"
|
||||
#define XC_SHM_IMPL
|
||||
#define XC_MEM_IMPL
|
||||
#include "xc_shm.h"
|
||||
#include "align.h"
|
||||
|
||||
#ifdef TEST
|
||||
|
@ -36,6 +38,8 @@ struct _xc_block_t {
|
|||
};
|
||||
|
||||
struct _xc_mem_t {
|
||||
const xc_mem_handlers_t *handlers;
|
||||
xc_shm_t *shm;
|
||||
xc_memsize_t size;
|
||||
xc_memsize_t avail; /* total free */
|
||||
xc_block_t headblock[1]; /* just as a pointer to first block*/
|
||||
|
@ -74,7 +78,7 @@ static void xc_block_check(xc_block_t *b) /* {{{ */
|
|||
#endif
|
||||
|
||||
|
||||
void *xc_mem_malloc(xc_mem_t *mem, xc_memsize_t size) /* {{{ */
|
||||
static XC_MEM_MALLOC(xc_mem_malloc) /* {{{ */
|
||||
{
|
||||
xc_block_t *prev, *cur;
|
||||
xc_block_t *newb, *b;
|
||||
|
@ -182,7 +186,7 @@ void *xc_mem_malloc(xc_mem_t *mem, xc_memsize_t size) /* {{{ */
|
|||
return p;
|
||||
}
|
||||
/* }}} */
|
||||
int xc_mem_free(xc_mem_t *mem, const void *p) /* {{{ return block size freed */
|
||||
static XC_MEM_FREE(xc_mem_free) /* {{{ return block size freed */
|
||||
{
|
||||
xc_block_t *cur, *b;
|
||||
int size;
|
||||
|
@ -236,7 +240,7 @@ int xc_mem_free(xc_mem_t *mem, const void *p) /* {{{ return block size freed */
|
|||
return size;
|
||||
}
|
||||
/* }}} */
|
||||
void *xc_mem_calloc(xc_mem_t *mem, xc_memsize_t memb, xc_memsize_t size) /* {{{ */
|
||||
static XC_MEM_CALLOC(xc_mem_calloc) /* {{{ */
|
||||
{
|
||||
xc_memsize_t realsize = memb * size;
|
||||
void *p = xc_mem_malloc(mem, realsize);
|
||||
|
@ -247,7 +251,7 @@ void *xc_mem_calloc(xc_mem_t *mem, xc_memsize_t memb, xc_memsize_t size) /* {{{
|
|||
return p;
|
||||
}
|
||||
/* }}} */
|
||||
void *xc_mem_realloc(xc_mem_t *mem, const void *p, xc_memsize_t size) /* {{{ */
|
||||
static XC_MEM_REALLOC(xc_mem_realloc) /* {{{ */
|
||||
{
|
||||
void *newp = xc_mem_malloc(mem, size);
|
||||
if (p) {
|
||||
|
@ -257,7 +261,7 @@ void *xc_mem_realloc(xc_mem_t *mem, const void *p, xc_memsize_t size) /* {{{ */
|
|||
return newp;
|
||||
}
|
||||
/* }}} */
|
||||
char *xc_mem_strndup(xc_mem_t *mem, const char *str, xc_memsize_t len) /* {{{ */
|
||||
static XC_MEM_STRNDUP(xc_mem_strndup) /* {{{ */
|
||||
{
|
||||
void *p = xc_mem_malloc(mem, len + 1);
|
||||
if (p) {
|
||||
|
@ -266,56 +270,54 @@ char *xc_mem_strndup(xc_mem_t *mem, const char *str, xc_memsize_t len) /* {{{ */
|
|||
return p;
|
||||
}
|
||||
/* }}} */
|
||||
char *xc_mem_strdup(xc_mem_t *mem, const char *str) /* {{{ */
|
||||
static XC_MEM_STRDUP(xc_mem_strdup) /* {{{ */
|
||||
{
|
||||
return xc_mem_strndup(mem, str, strlen(str));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
xc_memsize_t xc_mem_avail(xc_mem_t *mem) /* {{{ */
|
||||
static XC_MEM_AVAIL(xc_mem_avail) /* {{{ */
|
||||
{
|
||||
return mem->avail;
|
||||
}
|
||||
/* }}} */
|
||||
xc_memsize_t xc_mem_size(xc_mem_t *mem) /* {{{ */
|
||||
static XC_MEM_SIZE(xc_mem_size) /* {{{ */
|
||||
{
|
||||
return mem->size;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
const xc_block_t *xc_mem_freeblock_first(xc_mem_t *mem) /* {{{ */
|
||||
static XC_MEM_FREEBLOCK_FIRST(xc_mem_freeblock_first) /* {{{ */
|
||||
{
|
||||
return mem->headblock->next;
|
||||
}
|
||||
/* }}} */
|
||||
const xc_block_t *xc_mem_freeblock_next(const xc_block_t *block) /* {{{ */
|
||||
XC_MEM_FREEBLOCK_NEXT(xc_mem_freeblock_next) /* {{{ */
|
||||
{
|
||||
return block->next;
|
||||
}
|
||||
/* }}} */
|
||||
xc_memsize_t xc_mem_block_size(const xc_block_t *block) /* {{{ */
|
||||
XC_MEM_BLOCK_SIZE(xc_mem_block_size) /* {{{ */
|
||||
{
|
||||
return block->size;
|
||||
}
|
||||
/* }}} */
|
||||
xc_memsize_t xc_mem_block_offset(const xc_mem_t *mem, const xc_block_t *block) /* {{{ */
|
||||
XC_MEM_BLOCK_OFFSET(xc_mem_block_offset) /* {{{ */
|
||||
{
|
||||
return ((char *) block) - ((char *) mem);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
xc_mem_t *xc_mem_init(void *ptr, xc_memsize_t size) /* {{{ */
|
||||
static XC_MEM_INIT(xc_mem_init) /* {{{ */
|
||||
{
|
||||
xc_mem_t *mem;
|
||||
xc_block_t *b;
|
||||
|
||||
#define MINSIZE (ALIGN(sizeof(xc_mem_t)) + sizeof(xc_block_t))
|
||||
/* requires at least the header and 1 tail block */
|
||||
if (size < MINSIZE) {
|
||||
fprintf(stderr, "xc_mem_init requires %d bytes at least\n", MINSIZE);
|
||||
return NULL;
|
||||
}
|
||||
mem = (xc_mem_t *) ptr;
|
||||
mem->shm = shm;
|
||||
mem->size = size;
|
||||
mem->avail = size - MINSIZE;
|
||||
|
||||
|
@ -331,7 +333,7 @@ xc_mem_t *xc_mem_init(void *ptr, xc_memsize_t size) /* {{{ */
|
|||
return mem;
|
||||
}
|
||||
/* }}} */
|
||||
void xc_mem_destroy(xc_mem_t *mem) /* {{{ */
|
||||
static XC_MEM_DESTROY(xc_mem_destroy) /* {{{ */
|
||||
{
|
||||
}
|
||||
/* }}} */
|
||||
|
@ -380,3 +382,45 @@ int main()
|
|||
}
|
||||
/* }}} */
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
const xc_mem_handlers_t *handlers;
|
||||
} xc_mem_scheme_t;
|
||||
static xc_mem_scheme_t xc_mem_schemes[10];
|
||||
|
||||
int xc_mem_scheme_register(const char *name, const xc_mem_handlers_t *handlers) /* {{{ */
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 10; i ++) {
|
||||
if (!xc_mem_schemes[i].name) {
|
||||
xc_mem_schemes[i].name = name;
|
||||
xc_mem_schemes[i].handlers = handlers;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
const xc_mem_handlers_t *xc_mem_scheme_find(const char *name) /* {{{ */
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 10 && xc_mem_schemes[i].name; i ++) {
|
||||
if (strcmp(xc_mem_schemes[i].name, name) == 0) {
|
||||
return xc_mem_schemes[i].handlers;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static xc_mem_handlers_t xc_mem_mem_handlers = XC_MEM_HANDLERS(mem);
|
||||
void xc_shm_mem_init() /* {{{ */
|
||||
{
|
||||
memset(xc_mem_schemes, 0, sizeof(xc_mem_schemes));
|
||||
|
||||
if (xc_mem_scheme_register("mem", &xc_mem_mem_handlers) == 0) {
|
||||
zend_error(E_ERROR, "XCache: failed to register mem mem_scheme");
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
|
74
mem.h
74
mem.h
|
@ -2,19 +2,65 @@ typedef struct _xc_mem_t xc_mem_t;
|
|||
typedef struct _xc_block_t xc_block_t;
|
||||
typedef unsigned int xc_memsize_t;
|
||||
|
||||
void *xc_mem_malloc(xc_mem_t *mem, xc_memsize_t size);
|
||||
int xc_mem_free(xc_mem_t *mem, const void *p);
|
||||
void *xc_mem_calloc(xc_mem_t *mem, xc_memsize_t memb, xc_memsize_t size);
|
||||
void *xc_mem_realloc(xc_mem_t *mem, const void *p, xc_memsize_t size);
|
||||
char *xc_mem_strndup(xc_mem_t *mem, const char *str, xc_memsize_t len);
|
||||
char *xc_mem_strdup(xc_mem_t *mem, const char *str);
|
||||
const xc_block_t *xc_mem_freeblock_first(xc_mem_t *mem);
|
||||
const xc_block_t *xc_mem_freeblock_next(const xc_block_t *block);
|
||||
xc_memsize_t xc_mem_block_size(const xc_block_t *block);
|
||||
xc_memsize_t xc_mem_block_offset(const xc_mem_t *mem, const xc_block_t *block);
|
||||
/* shm::mem */
|
||||
#define XC_MEM_MALLOC(func) void *func(xc_mem_t *mem, xc_memsize_t size)
|
||||
#define XC_MEM_FREE(func) xc_memsize_t func(xc_mem_t *mem, const void *p)
|
||||
#define XC_MEM_CALLOC(func) void *func(xc_mem_t *mem, xc_memsize_t memb, xc_memsize_t size)
|
||||
#define XC_MEM_REALLOC(func) void *func(xc_mem_t *mem, const void *p, xc_memsize_t size)
|
||||
#define XC_MEM_STRNDUP(func) char *func(xc_mem_t *mem, const char *str, xc_memsize_t len)
|
||||
#define XC_MEM_STRDUP(func) char *func(xc_mem_t *mem, const char *str)
|
||||
#define XC_MEM_AVAIL(func) xc_memsize_t func(xc_mem_t *mem)
|
||||
#define XC_MEM_SIZE(func) xc_memsize_t func(xc_mem_t *mem)
|
||||
#define XC_MEM_FREEBLOCK_FIRST(func) const xc_block_t *func(xc_mem_t *mem)
|
||||
#define XC_MEM_FREEBLOCK_NEXT(func) const xc_block_t *func(const xc_block_t *block)
|
||||
#define XC_MEM_BLOCK_SIZE(func) xc_memsize_t func(const xc_block_t *block)
|
||||
#define XC_MEM_BLOCK_OFFSET(func) xc_memsize_t func(const xc_mem_t *mem, const xc_block_t *block)
|
||||
|
||||
xc_memsize_t xc_mem_avail(xc_mem_t *mem);
|
||||
xc_memsize_t xc_mem_size(xc_mem_t *mem);
|
||||
#define XC_MEM_INIT(func) xc_mem_t *func(xc_shm_t *shm, xc_mem_t *mem, xc_memsize_t size)
|
||||
#define XC_MEM_DESTROY(func) void func(xc_mem_t *mem)
|
||||
|
||||
xc_mem_t *xc_mem_init(void *ptr, xc_memsize_t size);
|
||||
void xc_mem_destroy(xc_mem_t *mem);
|
||||
#define XC_MEM_HANDLERS(name) { \
|
||||
xc_##name##_malloc \
|
||||
, xc_##name##_free \
|
||||
, xc_##name##_calloc \
|
||||
, xc_##name##_realloc \
|
||||
, xc_##name##_strndup \
|
||||
, xc_##name##_strdup \
|
||||
, xc_##name##_avail \
|
||||
, xc_##name##_size \
|
||||
, xc_##name##_freeblock_first \
|
||||
, xc_##name##_freeblock_next \
|
||||
, xc_##name##_block_size \
|
||||
, xc_##name##_block_offset \
|
||||
\
|
||||
, xc_##name##_init \
|
||||
, xc_##name##_destroy \
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
XC_MEM_MALLOC((*malloc));
|
||||
XC_MEM_FREE((*free));
|
||||
XC_MEM_CALLOC((*calloc));
|
||||
XC_MEM_REALLOC((*realloc));
|
||||
XC_MEM_STRNDUP((*strndup));
|
||||
XC_MEM_STRDUP((*strdup));
|
||||
XC_MEM_AVAIL((*avail));
|
||||
XC_MEM_SIZE((*size));
|
||||
XC_MEM_FREEBLOCK_FIRST((*freeblock_first));
|
||||
XC_MEM_FREEBLOCK_NEXT((*freeblock_next));
|
||||
XC_MEM_BLOCK_SIZE((*block_size));
|
||||
XC_MEM_BLOCK_OFFSET((*block_offset));
|
||||
|
||||
XC_MEM_INIT((*init));
|
||||
XC_MEM_DESTROY((*destroy));
|
||||
} xc_mem_handlers_t;
|
||||
|
||||
#ifndef XC_MEM_IMPL
|
||||
struct _xc_mem_t {
|
||||
const xc_mem_handlers_t *handlers;
|
||||
xc_shm_t *shm;
|
||||
};
|
||||
#endif
|
||||
|
||||
int xc_mem_scheme_register(const char *name, const xc_mem_handlers_t *handlers);
|
||||
const xc_mem_handlers_t *xc_mem_scheme_find(const char *name);
|
||||
|
|
59
mmap.c
59
mmap.c
|
@ -31,7 +31,8 @@
|
|||
#endif
|
||||
|
||||
#include "php.h"
|
||||
#include "myshm.h"
|
||||
#define XC_SHM_IMPL
|
||||
#include "xc_shm.h"
|
||||
|
||||
#ifndef max
|
||||
#define max(a, b) ((a) < (b) ? (b) : (a))
|
||||
|
@ -39,12 +40,14 @@
|
|||
|
||||
// {{{ xc_shm_t
|
||||
struct _xc_shm_t {
|
||||
xc_shm_handlers_t *handlers;
|
||||
void *ptr;
|
||||
void *ptr_ro;
|
||||
long diff;
|
||||
xc_shmsize_t size;
|
||||
char *name;
|
||||
int newfile;
|
||||
xc_shmsize_t memoffset;
|
||||
#ifdef ZEND_WIN32
|
||||
HANDLE hmap;
|
||||
HANDLE hmap_ro;
|
||||
|
@ -63,43 +66,43 @@ struct _xc_shm_t {
|
|||
#define PTR_ADD(ptr, v) (((char *) (ptr)) + (v))
|
||||
#define PTR_SUB(ptr, v) (((char *) (ptr)) - (v))
|
||||
|
||||
int xc_shm_can_readonly(xc_shm_t *shm) /* {{{ */
|
||||
static XC_SHM_CAN_READONLY(xc_mmap_can_readonly) /* {{{ */
|
||||
{
|
||||
return shm->ptr_ro != NULL;
|
||||
}
|
||||
/* }}} */
|
||||
int xc_shm_is_readwrite(xc_shm_t *shm, const void *p) /* {{{ */
|
||||
static XC_SHM_IS_READWRITE(xc_mmap_is_readwrite) /* {{{ */
|
||||
{
|
||||
return p >= shm->ptr && (char *)p < (char *)shm->ptr + shm->size;
|
||||
}
|
||||
/* }}} */
|
||||
int xc_shm_is_readonly(xc_shm_t *shm, const void *p) /* {{{ */
|
||||
static XC_SHM_IS_READONLY(xc_mmap_is_readonly) /* {{{ */
|
||||
{
|
||||
return xc_shm_can_readonly(shm) && p >= shm->ptr_ro && (char *)p < (char *)shm->ptr_ro + shm->size;
|
||||
return xc_mmap_can_readonly(shm) && p >= shm->ptr_ro && (char *)p < (char *)shm->ptr_ro + shm->size;
|
||||
}
|
||||
/* }}} */
|
||||
void *xc_shm_to_readwrite(xc_shm_t *shm, void *p) /* {{{ */
|
||||
static XC_SHM_TO_READWRITE(xc_mmap_to_readwrite) /* {{{ */
|
||||
{
|
||||
if (shm->diff) {
|
||||
assert(xc_shm_is_readonly(p));
|
||||
assert(xc_mmap_is_readonly(p));
|
||||
p = PTR_SUB(p, shm->diff);
|
||||
}
|
||||
assert(xc_shm_is_readwrite(p));
|
||||
assert(xc_mmap_is_readwrite(p));
|
||||
return p;
|
||||
}
|
||||
/* }}} */
|
||||
void *xc_shm_to_readonly(xc_shm_t *shm, void *p) /* {{{ */
|
||||
static XC_SHM_TO_READONLY(xc_mmap_to_readonly) /* {{{ */
|
||||
{
|
||||
assert(xc_shm_is_readwrite(p));
|
||||
if (shm->diff) {
|
||||
p = PTR_ADD(p, shm->diff);
|
||||
assert(xc_shm_is_readonly(p));
|
||||
assert(xc_mmap_is_readonly(p));
|
||||
}
|
||||
return p;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void xc_shm_destroy(xc_shm_t *shm) /* {{{ */
|
||||
static XC_SHM_DESTROY(xc_mmap_destroy) /* {{{ */
|
||||
{
|
||||
if (shm->ptr_ro) {
|
||||
munmap(shm->ptr_ro, shm->size);
|
||||
|
@ -140,7 +143,7 @@ void xc_shm_destroy(xc_shm_t *shm) /* {{{ */
|
|||
return;
|
||||
}
|
||||
/* }}} */
|
||||
xc_shm_t *xc_shm_init(const char *path, xc_shmsize_t size, zend_bool readonly_protection) /* {{{ */
|
||||
static XC_SHM_INIT(xc_mmap_init) /* {{{ */
|
||||
{
|
||||
#ifdef ZEND_WIN32
|
||||
# define TMP_PATH "XCache"
|
||||
|
@ -153,6 +156,7 @@ xc_shm_t *xc_shm_init(const char *path, xc_shmsize_t size, zend_bool readonly_pr
|
|||
volatile void *romem;
|
||||
char tmpname[sizeof(TMP_PATH) - 1 + 100];
|
||||
const char *errstr = NULL;
|
||||
const char *path = (const char *) arg1;
|
||||
|
||||
CHECK(shm = calloc(1, sizeof(xc_shm_t)), "shm OOM");
|
||||
shm->size = size;
|
||||
|
@ -272,7 +276,7 @@ err:
|
|||
close(fd);
|
||||
}
|
||||
if (shm) {
|
||||
xc_shm_destroy(shm);
|
||||
xc_mmap_destroy(shm);
|
||||
}
|
||||
if (errstr) {
|
||||
fprintf(stderr, "%s\n", errstr);
|
||||
|
@ -282,8 +286,33 @@ err:
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
void *xc_shm_ptr(xc_shm_t *shm) /* {{{ */
|
||||
static XC_SHM_MEMINIT(xc_mmap_meminit) /* {{{ */
|
||||
{
|
||||
return shm->ptr;
|
||||
xc_mem_t *mem;
|
||||
if (shm->memoffset + size > shm->size) {
|
||||
zend_error(E_ERROR, "XCache: internal error at %s#%d", __FILE__, __LINE__);
|
||||
return NULL;
|
||||
}
|
||||
mem = (xc_mem_t *) PTR_ADD(shm->ptr, shm->memoffset);
|
||||
shm->memoffset += size;
|
||||
mem->handlers = shm->handlers->memhandlers;
|
||||
mem->handlers->init(shm, mem, size);
|
||||
return mem;
|
||||
}
|
||||
/* }}} */
|
||||
static XC_SHM_MEMDESTROY(xc_mmap_memdestroy) /* {{{ */
|
||||
{
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static xc_shm_handlers_t xc_shm_mmap_handlers = XC_SHM_HANDLERS(mmap);
|
||||
void xc_shm_mmap_register() /* {{{ */
|
||||
{
|
||||
CHECK(xc_shm_mmap_handlers.memhandlers = xc_mem_scheme_find("mem"), "cannot find mem handlers");
|
||||
if (xc_shm_scheme_register("mmap", &xc_shm_mmap_handlers) == 0) {
|
||||
zend_error(E_ERROR, "XCache: failed to register mmap shm_scheme");
|
||||
}
|
||||
err:
|
||||
return;
|
||||
}
|
||||
/* }}} */
|
||||
|
|
13
myshm.h
13
myshm.h
|
@ -1,13 +0,0 @@
|
|||
typedef struct _xc_shm_t xc_shm_t;
|
||||
typedef size_t xc_shmsize_t;
|
||||
|
||||
int xc_shm_can_readonly(xc_shm_t *shm);
|
||||
int xc_shm_is_readwrite(xc_shm_t *shm, const void *p);
|
||||
int xc_shm_is_readonly(xc_shm_t *shm, const void *p);
|
||||
void *xc_shm_to_readwrite(xc_shm_t *shm, void *p);
|
||||
void *xc_shm_to_readonly(xc_shm_t *shm, void *p);
|
||||
|
||||
void *xc_shm_ptr(xc_shm_t *shm);
|
||||
|
||||
xc_shm_t *xc_shm_init(const char *path, xc_shmsize_t size, zend_bool readonly_protection);
|
||||
void xc_shm_destroy(xc_shm_t *shm);
|
|
@ -287,7 +287,7 @@ xc_entry_t *xc_processor_store_xc_entry_t(xc_entry_t *src TSRMLS_DC) {
|
|||
}
|
||||
|
||||
/* mem :) */
|
||||
processor.p = (char *)xc_mem_malloc(src->cache->mem, processor.size);
|
||||
processor.p = (char *) src->cache->mem->handlers->malloc(src->cache->mem, processor.size);
|
||||
if (processor.p == NULL) {
|
||||
dst = NULL;
|
||||
goto err_alloc;
|
||||
|
|
|
@ -117,11 +117,11 @@ dnl }}}
|
|||
dnl {{{ FIXPOINTER
|
||||
define(`FIXPOINTER', `FIXPOINTER_EX(`$1', `dst->$2')')
|
||||
define(`FIXPOINTER_EX', `IFSTORE(`
|
||||
$2 = ($1 *) xc_shm_to_readonly(processor->xce_src->cache->shm, (char *)$2);
|
||||
$2 = ($1 *) processor->xce_src->cache->shm->handlers->to_readonly(processor->xce_src->cache->shm, (char *)$2);
|
||||
')')
|
||||
define(`UNFIXPOINTER', `UNFIXPOINTER_EX(`$1', `dst->$2')')
|
||||
define(`UNFIXPOINTER_EX', `IFSTORE(`
|
||||
$2 = ($1 *) xc_shm_to_readwrite(processor->xce_src->cache->shm, (char *)$2);
|
||||
$2 = ($1 *) processor->xce_src->cache->shm->handlers->to_readwrite(processor->xce_src->cache->shm, (char *)$2);
|
||||
')')
|
||||
dnl }}}
|
||||
dnl {{{ COPY
|
||||
|
|
2
utils.c
2
utils.c
|
@ -403,8 +403,6 @@ static void xc_sandbox_install(xc_sandbox_t *sandbox TSRMLS_DC) /* {{{ */
|
|||
{
|
||||
int i;
|
||||
Bucket *b;
|
||||
zend_llist_position lpos;
|
||||
zend_file_handle *handle;
|
||||
|
||||
#ifdef HAVE_XCACHE_CONSTANT
|
||||
b = TG(zend_constants).pListHead;
|
||||
|
|
|
@ -0,0 +1,212 @@
|
|||
#define XC_SHM_IMPL
|
||||
#define XC_MEM_IMPL
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "xc_shm.h"
|
||||
#include "php.h"
|
||||
#include "align.h"
|
||||
|
||||
struct _xc_mem_t {
|
||||
const xc_mem_handlers_t *handlers;
|
||||
xc_shm_t *shm;
|
||||
xc_memsize_t size;
|
||||
xc_memsize_t avail; /* total free */
|
||||
};
|
||||
|
||||
#define CHECK(x, e) do { if ((x) == NULL) { zend_error(E_ERROR, "XCache: " e); goto err; } } while (0)
|
||||
|
||||
static XC_MEM_MALLOC(xc_malloc_malloc) /* {{{ */
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
/* }}} */
|
||||
static XC_MEM_FREE(xc_malloc_free) /* {{{ return block size freed */
|
||||
{
|
||||
free((void *) p);
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
static XC_MEM_CALLOC(xc_malloc_calloc) /* {{{ */
|
||||
{
|
||||
return calloc(memb, size);
|
||||
}
|
||||
/* }}} */
|
||||
static XC_MEM_REALLOC(xc_malloc_realloc) /* {{{ */
|
||||
{
|
||||
return realloc((void *) p, size);
|
||||
}
|
||||
/* }}} */
|
||||
static XC_MEM_STRNDUP(xc_malloc_strndup) /* {{{ */
|
||||
{
|
||||
char *p = malloc(len);
|
||||
if (!p) {
|
||||
return NULL;
|
||||
}
|
||||
return memcpy(p, str, len);
|
||||
}
|
||||
/* }}} */
|
||||
static XC_MEM_STRDUP(xc_malloc_strdup) /* {{{ */
|
||||
{
|
||||
return xc_malloc_strndup(mem, str, strlen(str) + 1);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static XC_MEM_AVAIL(xc_malloc_avail) /* {{{ */
|
||||
{
|
||||
return mem->avail;
|
||||
}
|
||||
/* }}} */
|
||||
static XC_MEM_SIZE(xc_malloc_size) /* {{{ */
|
||||
{
|
||||
return mem->size;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static XC_MEM_FREEBLOCK_FIRST(xc_malloc_freeblock_first) /* {{{ */
|
||||
{
|
||||
return (void *) -1;
|
||||
}
|
||||
/* }}} */
|
||||
XC_MEM_FREEBLOCK_NEXT(xc_malloc_freeblock_next) /* {{{ */
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
/* }}} */
|
||||
XC_MEM_BLOCK_SIZE(xc_malloc_block_size) /* {{{ */
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
XC_MEM_BLOCK_OFFSET(xc_malloc_block_offset) /* {{{ */
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static XC_MEM_INIT(xc_mem_malloc_init) /* {{{ */
|
||||
{
|
||||
xc_block_t *b;
|
||||
|
||||
#define MINSIZE (ALIGN(sizeof(xc_mem_t)))
|
||||
/* requires at least the header and 1 tail block */
|
||||
if (size < MINSIZE) {
|
||||
fprintf(stderr, "xc_mem_malloc_init requires %d bytes at least\n", MINSIZE);
|
||||
return NULL;
|
||||
}
|
||||
mem->shm = shm;
|
||||
mem->size = size;
|
||||
mem->avail = size - MINSIZE;
|
||||
#undef MINSIZE
|
||||
|
||||
return mem;
|
||||
}
|
||||
/* }}} */
|
||||
static XC_MEM_DESTROY(xc_mem_malloc_destroy) /* {{{ */
|
||||
{
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
// {{{ xc_shm_t
|
||||
struct _xc_shm_t {
|
||||
xc_shm_handlers_t *handlers;
|
||||
xc_shmsize_t size;
|
||||
xc_shmsize_t memoffset;
|
||||
};
|
||||
|
||||
#undef NDEBUG
|
||||
#ifdef ALLOC_DEBUG
|
||||
# define inline
|
||||
#else
|
||||
# define NDEBUG
|
||||
#endif
|
||||
#include <assert.h>
|
||||
/* }}} */
|
||||
|
||||
static XC_SHM_CAN_READONLY(xc_malloc_can_readonly) /* {{{ */
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
static XC_SHM_IS_READWRITE(xc_malloc_is_readwrite) /* {{{ */
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
static XC_SHM_IS_READONLY(xc_malloc_is_readonly) /* {{{ */
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
static XC_SHM_TO_READWRITE(xc_malloc_to_readwrite) /* {{{ */
|
||||
{
|
||||
return p;
|
||||
}
|
||||
/* }}} */
|
||||
static XC_SHM_TO_READONLY(xc_malloc_to_readonly) /* {{{ */
|
||||
{
|
||||
return p;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static XC_SHM_DESTROY(xc_malloc_destroy) /* {{{ */
|
||||
{
|
||||
free(shm);
|
||||
return;
|
||||
}
|
||||
/* }}} */
|
||||
static XC_SHM_INIT(xc_malloc_init) /* {{{ */
|
||||
{
|
||||
xc_shm_t *shm;
|
||||
CHECK(shm = calloc(1, sizeof(xc_shm_t)), "shm OOM");
|
||||
shm->size = size;
|
||||
|
||||
return shm;
|
||||
err:
|
||||
return NULL;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static XC_SHM_MEMINIT(xc_malloc_meminit) /* {{{ */
|
||||
{
|
||||
xc_mem_t *mem;
|
||||
if (shm->memoffset + size > shm->size) {
|
||||
zend_error(E_ERROR, "XCache: internal error at %s#%d", __FILE__, __LINE__);
|
||||
return NULL;
|
||||
}
|
||||
shm->memoffset += size;
|
||||
CHECK(mem = calloc(1, sizeof(xc_mem_t)), "mem OOM");
|
||||
mem->handlers = shm->handlers->memhandlers;
|
||||
mem->handlers->init(shm, mem, size);
|
||||
return mem;
|
||||
err:
|
||||
return NULL;
|
||||
}
|
||||
/* }}} */
|
||||
static XC_SHM_MEMDESTROY(xc_malloc_memdestroy) /* {{{ */
|
||||
{
|
||||
mem->handlers->destroy(mem);
|
||||
free(mem);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#define xc_malloc_destroy xc_mem_malloc_destroy
|
||||
#define xc_malloc_init xc_mem_malloc_init
|
||||
static xc_mem_handlers_t xc_mem_malloc_handlers = XC_MEM_HANDLERS(malloc);
|
||||
#undef xc_malloc_init
|
||||
#undef xc_malloc_destroy
|
||||
static xc_shm_handlers_t xc_shm_malloc_handlers = XC_SHM_HANDLERS(malloc);
|
||||
void xc_shm_malloc_register() /* {{{ */
|
||||
{
|
||||
if (xc_mem_scheme_register("malloc", &xc_mem_malloc_handlers) == 0) {
|
||||
zend_error(E_ERROR, "XCache: failed to register malloc mem_scheme");
|
||||
}
|
||||
|
||||
CHECK(xc_shm_malloc_handlers.memhandlers = xc_mem_scheme_find("malloc"), "cannot find malloc handlers");
|
||||
if (xc_shm_scheme_register("malloc", &xc_shm_malloc_handlers) == 0) {
|
||||
zend_error(E_ERROR, "XCache: failed to register malloc shm_scheme");
|
||||
}
|
||||
err:
|
||||
return;
|
||||
}
|
||||
/* }}} */
|
|
@ -0,0 +1,76 @@
|
|||
#ifdef TEST
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#else
|
||||
#include <php.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "xc_shm.h"
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
const xc_shm_handlers_t *handlers;
|
||||
} xc_shm_scheme_t;
|
||||
static xc_shm_scheme_t xc_shm_schemes[10];
|
||||
|
||||
void xc_shm_init_modules() /* {{{ */
|
||||
{
|
||||
memset(xc_shm_schemes, 0, sizeof(xc_shm_schemes));
|
||||
|
||||
extern void xc_shm_mem_init();
|
||||
xc_shm_mem_init();
|
||||
|
||||
extern void xc_shm_malloc_register();
|
||||
xc_shm_malloc_register();
|
||||
|
||||
extern void xc_shm_mmap_register();
|
||||
xc_shm_mmap_register();
|
||||
}
|
||||
/* }}} */
|
||||
int xc_shm_scheme_register(const char *name, const xc_shm_handlers_t *handlers) /* {{{ */
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 10; i ++) {
|
||||
if (!xc_shm_schemes[i].name) {
|
||||
xc_shm_schemes[i].name = name;
|
||||
xc_shm_schemes[i].handlers = handlers;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
const xc_shm_handlers_t *xc_shm_scheme_find(const char *name) /* {{{ */
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 10 && xc_shm_schemes[i].name; i ++) {
|
||||
if (strcmp(xc_shm_schemes[i].name, name) == 0) {
|
||||
return xc_shm_schemes[i].handlers;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/* }}} */
|
||||
xc_shm_t *xc_shm_init(const char *type, xc_shmsize_t size, int readonly_protection, const void *arg1, const void *arg2) /* {{{ */
|
||||
{
|
||||
const xc_shm_handlers_t *handlers = xc_shm_scheme_find(type);
|
||||
|
||||
if (handlers) {
|
||||
xc_shm_t *shm = handlers->init(size, readonly_protection, arg1, arg2);
|
||||
if (shm) {
|
||||
shm->handlers = handlers;
|
||||
}
|
||||
return shm;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
/* }}} */
|
||||
void xc_shm_destroy(xc_shm_t *shm) /* {{{ */
|
||||
{
|
||||
shm->handlers->destroy(shm);
|
||||
}
|
||||
/* }}} */
|
|
@ -0,0 +1,60 @@
|
|||
typedef struct _xc_shm_t xc_shm_t;
|
||||
typedef size_t xc_shmsize_t;
|
||||
|
||||
#include "mem.h"
|
||||
|
||||
/* shm */
|
||||
#define XC_SHM_CAN_READONLY(func) int func(xc_shm_t *shm)
|
||||
#define XC_SHM_IS_READWRITE(func) int func(xc_shm_t *shm, const void *p)
|
||||
#define XC_SHM_IS_READONLY(func) int func(xc_shm_t *shm, const void *p)
|
||||
#define XC_SHM_TO_READWRITE(func) void *func(xc_shm_t *shm, void *p)
|
||||
#define XC_SHM_TO_READONLY(func) void *func(xc_shm_t *shm, void *p)
|
||||
|
||||
#define XC_SHM_INIT(func) xc_shm_t *func(xc_shmsize_t size, int readonly_protection, const void *arg1, const void *arg2)
|
||||
#define XC_SHM_DESTROY(func) void func(xc_shm_t *shm)
|
||||
|
||||
#define XC_SHM_MEMINIT(func) xc_mem_t *func(xc_shm_t *shm, xc_memsize_t size)
|
||||
#define XC_SHM_MEMDESTROY(func) void func(xc_mem_t *mem)
|
||||
|
||||
#define XC_SHM_HANDLERS(name) { \
|
||||
NULL \
|
||||
, xc_##name##_can_readonly \
|
||||
, xc_##name##_is_readwrite \
|
||||
, xc_##name##_is_readonly \
|
||||
, xc_##name##_to_readwrite \
|
||||
, xc_##name##_to_readonly \
|
||||
\
|
||||
, xc_##name##_init \
|
||||
, xc_##name##_destroy \
|
||||
\
|
||||
, xc_##name##_meminit \
|
||||
, xc_##name##_memdestroy \
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
const xc_mem_handlers_t *memhandlers;
|
||||
XC_SHM_CAN_READONLY((*can_readonly));
|
||||
XC_SHM_IS_READWRITE((*is_readwrite));
|
||||
XC_SHM_IS_READONLY((*is_readonly));
|
||||
XC_SHM_TO_READWRITE((*to_readwrite));
|
||||
XC_SHM_TO_READONLY((*to_readonly));
|
||||
XC_SHM_INIT((*init));
|
||||
XC_SHM_DESTROY((*destroy));
|
||||
|
||||
XC_SHM_MEMINIT((*meminit));
|
||||
XC_SHM_MEMDESTROY((*memdestroy));
|
||||
} xc_shm_handlers_t;
|
||||
|
||||
|
||||
#ifndef XC_SHM_IMPL
|
||||
struct _xc_shm_t {
|
||||
const xc_shm_handlers_t *handlers;
|
||||
};
|
||||
#endif
|
||||
|
||||
void xc_shm_init_modules();
|
||||
int xc_shm_scheme_register(const char *name, const xc_shm_handlers_t *handlers);
|
||||
const xc_shm_handlers_t *xc_shm_scheme_find(const char *name);
|
||||
|
||||
xc_shm_t *xc_shm_init(const char *type, xc_shmsize_t size, int readonly_protection, const void *arg1, const void *arg2);
|
||||
void xc_shm_destroy(xc_shm_t *shm);
|
86
xcache.c
86
xcache.c
|
@ -67,6 +67,7 @@
|
|||
/* }}} */
|
||||
|
||||
/* {{{ globals */
|
||||
static char *xc_shm_scheme = NULL;
|
||||
static char *xc_mmap_path = NULL;
|
||||
static char *xc_coredump_dir = NULL;
|
||||
|
||||
|
@ -150,7 +151,7 @@ static inline int xc_entry_equal_dmz(xc_entry_t *a, xc_entry_t *b) /* {{{ */
|
|||
/* }}} */
|
||||
static void xc_entry_free_real_dmz(volatile xc_entry_t *xce) /* {{{ */
|
||||
{
|
||||
xc_mem_free(xce->cache->mem, (xc_entry_t *)xce);
|
||||
xce->cache->mem->handlers->free(xce->cache->mem, (xc_entry_t *)xce);
|
||||
}
|
||||
/* }}} */
|
||||
static void xc_entry_add_dmz(xc_entry_t *xce) /* {{{ */
|
||||
|
@ -252,7 +253,6 @@ typedef XC_ENTRY_APPLY_FUNC((*cache_apply_dmz_func_t));
|
|||
static void xc_entry_apply_dmz(xc_cache_t *cache, cache_apply_dmz_func_t apply_func TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
xc_entry_t *p, **pp;
|
||||
xc_entry_t *next;
|
||||
int i, c;
|
||||
|
||||
for (i = 0, c = cache->hentry->size; i < c; i ++) {
|
||||
|
@ -394,6 +394,7 @@ static void xc_fillinfo_dmz(int cachetype, xc_cache_t *cache, zval *return_value
|
|||
xc_memsize_t avail = 0;
|
||||
#endif
|
||||
xc_mem_t *mem = cache->mem;
|
||||
const xc_mem_handlers_t *handlers = mem->handlers;
|
||||
zend_ulong interval = (cachetype == XC_TYPE_PHP) ? xc_php_gc_interval : xc_var_gc_interval;
|
||||
|
||||
add_assoc_long_ex(return_value, ZEND_STRS("slots"), cache->hentry->size);
|
||||
|
@ -415,25 +416,25 @@ static void xc_fillinfo_dmz(int cachetype, xc_cache_t *cache, zval *return_value
|
|||
MAKE_STD_ZVAL(blocks);
|
||||
array_init(blocks);
|
||||
|
||||
add_assoc_long_ex(return_value, ZEND_STRS("size"), xc_mem_size(mem));
|
||||
add_assoc_long_ex(return_value, ZEND_STRS("avail"), xc_mem_avail(mem));
|
||||
add_assoc_long_ex(return_value, ZEND_STRS("size"), handlers->size(mem));
|
||||
add_assoc_long_ex(return_value, ZEND_STRS("avail"), handlers->avail(mem));
|
||||
add_assoc_bool_ex(return_value, ZEND_STRS("can_readonly"), xc_readonly_protection);
|
||||
|
||||
for (b = xc_mem_freeblock_first(mem); b; b = xc_mem_freeblock_next(b)) {
|
||||
for (b = handlers->freeblock_first(mem); b; b = handlers->freeblock_next(b)) {
|
||||
zval *bi;
|
||||
|
||||
MAKE_STD_ZVAL(bi);
|
||||
array_init(bi);
|
||||
|
||||
add_assoc_long_ex(bi, ZEND_STRS("size"), xc_mem_block_size(b));
|
||||
add_assoc_long_ex(bi, ZEND_STRS("offset"), xc_mem_block_offset(mem, b));
|
||||
add_assoc_long_ex(bi, ZEND_STRS("size"), handlers->block_size(b));
|
||||
add_assoc_long_ex(bi, ZEND_STRS("offset"), handlers->block_offset(mem, b));
|
||||
add_next_index_zval(blocks, bi);
|
||||
#ifndef NDEBUG
|
||||
avail += xc_mem_block_size(b);
|
||||
avail += handlers->block_size(b);
|
||||
#endif
|
||||
}
|
||||
add_assoc_zval_ex(return_value, ZEND_STRS("free_blocks"), blocks);
|
||||
assert(avail == xc_mem_avail(mem));
|
||||
assert(avail == handlers->avail(mem));
|
||||
}
|
||||
/* }}} */
|
||||
static void xc_fillentry_dmz(xc_entry_t *entry, int del, zval *list TSRMLS_DC) /* {{{ */
|
||||
|
@ -1024,17 +1025,20 @@ restore:
|
|||
/* gdb helper functions, but N/A for coredump */
|
||||
int xc_is_rw(const void *p) /* {{{ */
|
||||
{
|
||||
xc_shm_t *shm;
|
||||
int i;
|
||||
if (!xc_initized) {
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < xc_php_hcache.size; i ++) {
|
||||
if (xc_shm_is_readwrite(xc_php_caches[i]->shm, p)) {
|
||||
shm = xc_php_caches[i]->shm;
|
||||
if (shm->handlers->is_readwrite(shm, p)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < xc_var_hcache.size; i ++) {
|
||||
if (xc_shm_is_readwrite(xc_var_caches[i]->shm, p)) {
|
||||
shm = xc_var_caches[i]->shm;
|
||||
if (shm->handlers->is_readwrite(shm, p)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -1043,17 +1047,20 @@ int xc_is_rw(const void *p) /* {{{ */
|
|||
/* }}} */
|
||||
int xc_is_ro(const void *p) /* {{{ */
|
||||
{
|
||||
xc_shm_t *shm;
|
||||
int i;
|
||||
if (!xc_initized) {
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < xc_php_hcache.size; i ++) {
|
||||
if (xc_shm_is_readonly(xc_php_caches[i]->shm, p)) {
|
||||
shm = xc_php_caches[i]->shm;
|
||||
if (shm->handlers->is_readonly(shm, p)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < xc_var_hcache.size; i ++) {
|
||||
if (xc_shm_is_readonly(xc_var_caches[i]->shm, p)) {
|
||||
shm = xc_var_caches[i]->shm;
|
||||
if (shm->handlers->is_readonly(shm, p)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -1127,11 +1134,11 @@ static xc_shm_t *xc_cache_destroy(xc_cache_t **caches, xc_hash_t *hcache) /* {{{
|
|||
}
|
||||
/* do NOT free
|
||||
if (cache->entries) {
|
||||
xc_mem_free(cache->mem, cache->entries);
|
||||
cache->mem->handlers->free(cache->mem, cache->entries);
|
||||
}
|
||||
xc_mem_free(cache->mem, cache);
|
||||
cache->mem->handlers->free(cache->mem, cache);
|
||||
*/
|
||||
xc_mem_destroy(cache->mem);
|
||||
shm->handlers->memdestroy(cache->mem);
|
||||
shm = cache->shm;
|
||||
}
|
||||
}
|
||||
|
@ -1139,7 +1146,7 @@ static xc_shm_t *xc_cache_destroy(xc_cache_t **caches, xc_hash_t *hcache) /* {{{
|
|||
return shm;
|
||||
}
|
||||
/* }}} */
|
||||
static xc_cache_t **xc_cache_init(xc_shm_t *shm, char *ptr, xc_hash_t *hcache, xc_hash_t *hentry, xc_shmsize_t shmsize) /* {{{ */
|
||||
static xc_cache_t **xc_cache_init(xc_shm_t *shm, xc_hash_t *hcache, xc_hash_t *hentry, xc_shmsize_t shmsize) /* {{{ */
|
||||
{
|
||||
xc_cache_t **caches = NULL, *cache;
|
||||
xc_mem_t *mem;
|
||||
|
@ -1163,10 +1170,9 @@ static xc_cache_t **xc_cache_init(xc_shm_t *shm, char *ptr, xc_hash_t *hcache, x
|
|||
CHECK(caches = calloc(hcache->size, sizeof(xc_cache_t *)), "caches OOM");
|
||||
|
||||
for (i = 0; i < hcache->size; i ++) {
|
||||
CHECK(mem = xc_mem_init(ptr, memsize), "Failed init memory allocator");
|
||||
ptr += memsize;
|
||||
CHECK(cache = xc_mem_calloc(mem, 1, sizeof(xc_cache_t)), "cache OOM");
|
||||
CHECK(cache->entries = xc_mem_calloc(mem, hentry->size, sizeof(xc_entry_t*)), "entries OOM");
|
||||
CHECK(mem = shm->handlers->meminit(shm, memsize), "Failed init memory allocator");
|
||||
CHECK(cache = mem->handlers->calloc(mem, 1, sizeof(xc_cache_t)), "cache OOM");
|
||||
CHECK(cache->entries = mem->handlers->calloc(mem, hentry->size, sizeof(xc_entry_t*)), "entries OOM");
|
||||
CHECK(cache->lck = xc_lock_init(NULL), "can't create lock");
|
||||
|
||||
cache->hcache = hcache;
|
||||
|
@ -1178,7 +1184,6 @@ static xc_cache_t **xc_cache_init(xc_shm_t *shm, char *ptr, xc_hash_t *hcache, x
|
|||
cache->last_gc_expires = now;
|
||||
caches[i] = cache;
|
||||
}
|
||||
assert(ptr <= (char*)xc_shm_ptr(shm) + shmsize);
|
||||
return caches;
|
||||
|
||||
err:
|
||||
|
@ -1213,27 +1218,24 @@ static void xc_destroy() /* {{{ */
|
|||
static int xc_init(int module_number TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
xc_shm_t *shm;
|
||||
char *ptr;
|
||||
|
||||
xc_php_caches = xc_var_caches = NULL;
|
||||
|
||||
if (xc_php_size || xc_var_size) {
|
||||
CHECK(shm = xc_shm_init(xc_mmap_path, ALIGN(xc_php_size) + ALIGN(xc_var_size), xc_readonly_protection), "Cannot create shm");
|
||||
if (!xc_shm_can_readonly(shm)) {
|
||||
CHECK(shm = xc_shm_init(xc_shm_scheme, ALIGN(xc_php_size) + ALIGN(xc_var_size), xc_readonly_protection, xc_mmap_path, NULL), "Cannot create shm");
|
||||
if (!shm->handlers->can_readonly(shm)) {
|
||||
xc_readonly_protection = 0;
|
||||
}
|
||||
|
||||
ptr = (char *)xc_shm_ptr(shm);
|
||||
if (xc_php_size) {
|
||||
origin_compile_file = zend_compile_file;
|
||||
zend_compile_file = xc_compile_file;
|
||||
|
||||
CHECK(xc_php_caches = xc_cache_init(shm, ptr, &xc_php_hcache, &xc_php_hentry, xc_php_size), "failed init opcode cache");
|
||||
ptr += ALIGN(xc_php_size);
|
||||
CHECK(xc_php_caches = xc_cache_init(shm, &xc_php_hcache, &xc_php_hentry, xc_php_size), "failed init opcode cache");
|
||||
}
|
||||
|
||||
if (xc_var_size) {
|
||||
CHECK(xc_var_caches = xc_cache_init(shm, ptr, &xc_var_hcache, &xc_var_hentry, xc_var_size), "failed init variable cache");
|
||||
CHECK(xc_var_caches = xc_cache_init(shm, &xc_var_hcache, &xc_var_hentry, xc_var_size), "failed init variable cache");
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
@ -2114,7 +2116,7 @@ PHP_INI_BEGIN()
|
|||
#endif
|
||||
PHP_INI_END()
|
||||
/* }}} */
|
||||
static int xc_config_long_disp(char *name, char *default_value) /* {{{ */
|
||||
static int xc_config_string_disp(char *name, char *default_value) /* {{{ */
|
||||
{
|
||||
char *value;
|
||||
char buf[100];
|
||||
|
@ -2130,7 +2132,8 @@ static int xc_config_long_disp(char *name, char *default_value) /* {{{ */
|
|||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
#define xc_config_hash_disp xc_config_long_disp
|
||||
#define xc_config_hash_disp xc_config_string_disp
|
||||
#define xc_config_long_disp xc_config_string_disp
|
||||
/* {{{ PHP_MINFO_FUNCTION(xcache) */
|
||||
static PHP_MINFO_FUNCTION(xcache)
|
||||
{
|
||||
|
@ -2138,7 +2141,7 @@ static PHP_MINFO_FUNCTION(xcache)
|
|||
char *ptr;
|
||||
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, "XCache Support", XCACHE_MODULES);
|
||||
php_info_print_table_header(2, "XCache Support", "enabled");
|
||||
php_info_print_table_row(2, "Version", XCACHE_VERSION);
|
||||
php_info_print_table_row(2, "Modules Built", XCACHE_MODULES);
|
||||
php_info_print_table_row(2, "Readonly Protection", xc_readonly_protection ? "enabled" : "N/A");
|
||||
|
@ -2168,6 +2171,7 @@ static PHP_MINFO_FUNCTION(xcache)
|
|||
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, "Directive ", "Value");
|
||||
xc_config_string_disp("xcache.shm_scheme", "mmap");
|
||||
xc_config_long_disp("xcache.size", "0");
|
||||
xc_config_hash_disp("xcache.count", "1");
|
||||
xc_config_hash_disp("xcache.slots", "8K");
|
||||
|
@ -2249,6 +2253,18 @@ static int xc_config_long(zend_ulong *p, char *name, char *default_value) /* {{{
|
|||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
static int xc_config_string(char **p, char *name, char *default_value) /* {{{ */
|
||||
{
|
||||
char *value;
|
||||
|
||||
if (cfg_get_string(name, &value) != SUCCESS) {
|
||||
value = default_value;
|
||||
}
|
||||
|
||||
*p = strdup(value);
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
/* {{{ PHP_MINIT_FUNCTION(xcache) */
|
||||
static PHP_MINIT_FUNCTION(xcache)
|
||||
{
|
||||
|
@ -2277,6 +2293,7 @@ static PHP_MINIT_FUNCTION(xcache)
|
|||
}
|
||||
}
|
||||
|
||||
xc_config_string(&xc_shm_scheme, "xcache.shm_scheme", "mmap");
|
||||
xc_config_long(&xc_php_size, "xcache.size", "0");
|
||||
xc_config_hash(&xc_php_hcache, "xcache.count", "1");
|
||||
xc_config_hash(&xc_php_hentry, "xcache.slots", "8K");
|
||||
|
@ -2301,6 +2318,7 @@ static PHP_MINIT_FUNCTION(xcache)
|
|||
}
|
||||
|
||||
xc_init_constant(module_number TSRMLS_CC);
|
||||
xc_shm_init_modules();
|
||||
|
||||
if ((xc_php_size || xc_var_size) && xc_mmap_path && xc_mmap_path[0]) {
|
||||
if (!xc_init(module_number TSRMLS_CC)) {
|
||||
|
@ -2331,6 +2349,10 @@ static PHP_MSHUTDOWN_FUNCTION(xcache)
|
|||
pefree(xc_mmap_path, 1);
|
||||
xc_mmap_path = NULL;
|
||||
}
|
||||
if (xc_shm_scheme) {
|
||||
pefree(xc_shm_scheme, 1);
|
||||
xc_shm_scheme = NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_XCACHE_COVERAGER
|
||||
xc_coverager_destroy();
|
||||
|
|
Loading…
Reference in New Issue