forked from enlightenment/efl
Patch from Arnaud de Turckheim "quarium" <quarium@gmail.com>.
Use magic inside stringshare without slowdown of benchmark. Fix magic when not in DEBUG mode. SVN revision: 36246
This commit is contained in:
parent
313771e7ec
commit
040e5573d9
|
@ -6,3 +6,4 @@ Gustavo Sverzut Barbieri <barbieri@gmail.com>
|
||||||
Tilman Sauerbeck <tilman@code-monkey.de>
|
Tilman Sauerbeck <tilman@code-monkey.de>
|
||||||
Cedric Bail <cedric.bail@free.fr>
|
Cedric Bail <cedric.bail@free.fr>
|
||||||
Peter "pfritz" Wehrfritz <peter.wehrfritz@web.de>
|
Peter "pfritz" Wehrfritz <peter.wehrfritz@web.de>
|
||||||
|
Arnaud de Turckheim "quarium" <quarium@gmail.com>
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
#define EINA_MAGIC_SET(d, m) (d)->__magic = (m)
|
#define EINA_MAGIC_SET(d, m) (d)->__magic = (m)
|
||||||
#define EINA_MAGIC_CHECK(d, m) ((d) && ((d)->__magic == (m)))
|
#define EINA_MAGIC_CHECK(d, m) ((d) && ((d)->__magic == (m)))
|
||||||
#define EINA_MAGIC_FAIL(d, m) eina_magic_fail((d), (d) ? (d)->__magic : 0, (m), __FILE__, __FUNCTION__, __LINE__);
|
#define EINA_MAGIC_FAIL(d, m) eina_magic_fail((void*)(d), (d) ? (d)->__magic : 0, (m), __FILE__, __FUNCTION__, __LINE__);
|
||||||
|
|
||||||
typedef unsigned int Eina_Magic;
|
typedef unsigned int Eina_Magic;
|
||||||
|
|
||||||
|
@ -43,16 +43,16 @@ EAPI void eina_magic_fail(void *d, Eina_Magic m, Eina_Magic req_m,
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define EINA_MAGIC_NONE (void)
|
#define EINA_MAGIC_NONE ((void) 0)
|
||||||
#define EINA_MAGIC
|
#define EINA_MAGIC
|
||||||
#define EINA_MAGIC_SET(d, m) (void)
|
#define EINA_MAGIC_SET(d, m) ((void) 0)
|
||||||
#define EINA_MAGIC_CHECK(d, m) (1)
|
#define EINA_MAGIC_CHECK(d, m) (1)
|
||||||
#define EINA_MAGIC_FAIL(d, m) (void)
|
#define EINA_MAGIC_FAIL(d, m) ((void) 0)
|
||||||
|
|
||||||
#define eina_magic_string_get(Magic) (NULL)
|
#define eina_magic_string_get(Magic) (NULL)
|
||||||
#define eina_magic_string_set(Magic, Magic_Name) (void)
|
#define eina_magic_string_set(Magic, Magic_Name) ((void) 0)
|
||||||
#define eina_magic_fail(d, m, req_m, file, fnx, line) (void)
|
#define eina_magic_fail(d, m, req_m, file, fnx, line) ((void) 0)
|
||||||
#define eina_magic_string_init() (0)
|
#define eina_magic_string_init() (1)
|
||||||
#define eina_magic_string_shutdown() (0)
|
#define eina_magic_string_shutdown() (0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include "eina_magic.h"
|
||||||
#include "eina_iterator.h"
|
#include "eina_iterator.h"
|
||||||
#include "eina_accessor.h"
|
#include "eina_accessor.h"
|
||||||
|
|
||||||
|
@ -46,15 +47,42 @@
|
||||||
|
|
||||||
#define READBUFSIZ 65536
|
#define READBUFSIZ 65536
|
||||||
|
|
||||||
|
/* eina magic types */
|
||||||
|
#define EINA_MAGIC_STRINGSHARE 0x10452571
|
||||||
|
#define EINA_MAGIC_STRINGSHARE_NODE 0x95204152
|
||||||
|
#define EINA_MAGIC_STRINGSHARE_HEAD 0x35294051
|
||||||
|
|
||||||
/* undef the following, we want out version */
|
/* undef the following, we want out version */
|
||||||
#undef FREE
|
#undef FREE
|
||||||
#define FREE(ptr) free(ptr); ptr = NULL;
|
#define FREE(ptr) \
|
||||||
|
do { \
|
||||||
|
free(ptr); \
|
||||||
|
ptr = NULL; \
|
||||||
|
} while(0);
|
||||||
|
|
||||||
#undef IF_FREE
|
#undef IF_FREE
|
||||||
#define IF_FREE(ptr) if (ptr) free(ptr); ptr = NULL;
|
#define IF_FREE(ptr) \
|
||||||
|
do { \
|
||||||
|
if (ptr) { \
|
||||||
|
free(ptr); \
|
||||||
|
ptr = NULL; \
|
||||||
|
} \
|
||||||
|
} while(0);
|
||||||
|
|
||||||
#undef IF_FN_DEL
|
#undef IF_FN_DEL
|
||||||
#define IF_FN_DEL(_fn, ptr) if (ptr) { _fn(ptr); ptr = NULL; }
|
#define IF_FN_DEL(_fn, ptr) \
|
||||||
|
do { \
|
||||||
|
if (ptr) { \
|
||||||
|
_fn(ptr); \
|
||||||
|
ptr = NULL; \
|
||||||
|
} \
|
||||||
|
} while(0);
|
||||||
|
|
||||||
|
#define MAGIC_FREE(ptr) \
|
||||||
|
do { \
|
||||||
|
EINA_MAGIC_SET(ptr, EINA_MAGIC_NONE); \
|
||||||
|
FREE(ptr); \
|
||||||
|
} while(0);
|
||||||
|
|
||||||
inline void eina_print_warning(const char *function, const char *sparam);
|
inline void eina_print_warning(const char *function, const char *sparam);
|
||||||
|
|
||||||
|
|
|
@ -24,12 +24,12 @@
|
||||||
|
|
||||||
#include "eina_array.h"
|
#include "eina_array.h"
|
||||||
#include "eina_error.h"
|
#include "eina_error.h"
|
||||||
#include "eina_private.h"
|
|
||||||
|
|
||||||
#ifndef DEBUG
|
#ifndef DEBUG
|
||||||
# define DEBUG
|
# define DEBUG
|
||||||
#endif
|
#endif
|
||||||
#include "eina_magic.h"
|
#include "eina_magic.h"
|
||||||
|
#include "eina_private.h"
|
||||||
|
|
||||||
/*============================================================================*
|
/*============================================================================*
|
||||||
* Local *
|
* Local *
|
||||||
|
|
|
@ -72,6 +72,7 @@
|
||||||
#include "eina_rbtree.h"
|
#include "eina_rbtree.h"
|
||||||
#include "eina_error.h"
|
#include "eina_error.h"
|
||||||
#include "eina_private.h"
|
#include "eina_private.h"
|
||||||
|
#include "eina_magic.h"
|
||||||
|
|
||||||
/*============================================================================*
|
/*============================================================================*
|
||||||
* Local *
|
* Local *
|
||||||
|
@ -84,6 +85,18 @@
|
||||||
#define EINA_STRINGSHARE_BUCKETS 256
|
#define EINA_STRINGSHARE_BUCKETS 256
|
||||||
#define EINA_STRINGSHARE_MASK 0xFF
|
#define EINA_STRINGSHARE_MASK 0xFF
|
||||||
|
|
||||||
|
#define EINA_MAGIC_CHECK_STRINGSHARE_HEAD(d) \
|
||||||
|
do { \
|
||||||
|
if (!EINA_MAGIC_CHECK((d), EINA_MAGIC_STRINGSHARE_HEAD)) \
|
||||||
|
EINA_MAGIC_FAIL((d), EINA_MAGIC_STRINGSHARE_HEAD); \
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
#define EINA_MAGIC_CHECK_STRINGSHARE_NODE(d) \
|
||||||
|
do { \
|
||||||
|
if (!EINA_MAGIC_CHECK((d), EINA_MAGIC_STRINGSHARE_NODE)) \
|
||||||
|
EINA_MAGIC_FAIL((d), EINA_MAGIC_STRINGSHARE_NODE); \
|
||||||
|
} while (0);
|
||||||
|
|
||||||
typedef struct _Eina_Stringshare Eina_Stringshare;
|
typedef struct _Eina_Stringshare Eina_Stringshare;
|
||||||
typedef struct _Eina_Stringshare_Node Eina_Stringshare_Node;
|
typedef struct _Eina_Stringshare_Node Eina_Stringshare_Node;
|
||||||
typedef struct _Eina_Stringshare_Head Eina_Stringshare_Head;
|
typedef struct _Eina_Stringshare_Head Eina_Stringshare_Head;
|
||||||
|
@ -91,11 +104,14 @@ typedef struct _Eina_Stringshare_Head Eina_Stringshare_Head;
|
||||||
struct _Eina_Stringshare
|
struct _Eina_Stringshare
|
||||||
{
|
{
|
||||||
Eina_Stringshare_Head *buckets[EINA_STRINGSHARE_BUCKETS];
|
Eina_Stringshare_Head *buckets[EINA_STRINGSHARE_BUCKETS];
|
||||||
|
|
||||||
|
EINA_MAGIC;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _Eina_Stringshare_Head
|
struct _Eina_Stringshare_Head
|
||||||
{
|
{
|
||||||
EINA_RBTREE;
|
EINA_RBTREE;
|
||||||
|
EINA_MAGIC;
|
||||||
int hash;
|
int hash;
|
||||||
|
|
||||||
Eina_Stringshare_Node *head;
|
Eina_Stringshare_Node *head;
|
||||||
|
@ -103,6 +119,8 @@ struct _Eina_Stringshare_Head
|
||||||
|
|
||||||
struct _Eina_Stringshare_Node
|
struct _Eina_Stringshare_Node
|
||||||
{
|
{
|
||||||
|
EINA_MAGIC;
|
||||||
|
|
||||||
Eina_Stringshare_Node *next;
|
Eina_Stringshare_Node *next;
|
||||||
|
|
||||||
int length;
|
int length;
|
||||||
|
@ -115,14 +133,19 @@ static Eina_Stringshare *share = NULL;
|
||||||
static int _eina_stringshare_init_count = 0;
|
static int _eina_stringshare_init_count = 0;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_eina_stringshare_cmp(const Eina_Stringshare_Head *node, const int *hash, __UNUSED__ int length, __UNUSED__ void *data)
|
_eina_stringshare_cmp(const Eina_Stringshare_Head *ed, const int *hash, __UNUSED__ int length, __UNUSED__ void *data)
|
||||||
{
|
{
|
||||||
return node->hash - *hash;
|
EINA_MAGIC_CHECK_STRINGSHARE_HEAD(ed);
|
||||||
|
|
||||||
|
return ed->hash - *hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Eina_Rbtree_Direction
|
static Eina_Rbtree_Direction
|
||||||
_eina_stringshare_node(const Eina_Stringshare_Head *left, const Eina_Stringshare_Head *right, __UNUSED__ void *data)
|
_eina_stringshare_node(const Eina_Stringshare_Head *left, const Eina_Stringshare_Head *right, __UNUSED__ void *data)
|
||||||
{
|
{
|
||||||
|
EINA_MAGIC_CHECK_STRINGSHARE_HEAD(left);
|
||||||
|
EINA_MAGIC_CHECK_STRINGSHARE_HEAD(right);
|
||||||
|
|
||||||
if (left->hash - right->hash < 0)
|
if (left->hash - right->hash < 0)
|
||||||
return EINA_RBTREE_LEFT;
|
return EINA_RBTREE_LEFT;
|
||||||
return EINA_RBTREE_RIGHT;
|
return EINA_RBTREE_RIGHT;
|
||||||
|
@ -131,14 +154,17 @@ _eina_stringshare_node(const Eina_Stringshare_Head *left, const Eina_Stringshare
|
||||||
static void
|
static void
|
||||||
_eina_stringshare_head_free(Eina_Stringshare_Head *ed, __UNUSED__ void *data)
|
_eina_stringshare_head_free(Eina_Stringshare_Head *ed, __UNUSED__ void *data)
|
||||||
{
|
{
|
||||||
|
EINA_MAGIC_CHECK_STRINGSHARE_HEAD(ed);
|
||||||
|
|
||||||
while (ed->head)
|
while (ed->head)
|
||||||
{
|
{
|
||||||
Eina_Stringshare_Node *el = ed->head;
|
Eina_Stringshare_Node *el = ed->head;
|
||||||
|
|
||||||
ed->head = ed->head->next;
|
ed->head = ed->head->next;
|
||||||
if (el->begin == EINA_FALSE) free(el);
|
if (el->begin == EINA_FALSE)
|
||||||
|
MAGIC_FREE(el);
|
||||||
}
|
}
|
||||||
free(ed);
|
MAGIC_FREE(ed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -206,11 +232,20 @@ eina_stringshare_init()
|
||||||
share = calloc(1, sizeof(Eina_Stringshare));
|
share = calloc(1, sizeof(Eina_Stringshare));
|
||||||
if (!share)
|
if (!share)
|
||||||
return 0;
|
return 0;
|
||||||
eina_error_init();
|
|
||||||
}
|
|
||||||
_eina_stringshare_init_count++;
|
|
||||||
|
|
||||||
return _eina_stringshare_init_count;
|
eina_error_init();
|
||||||
|
eina_magic_string_init();
|
||||||
|
|
||||||
|
eina_magic_string_set(EINA_MAGIC_STRINGSHARE,
|
||||||
|
"Eina Stringshare");
|
||||||
|
eina_magic_string_set(EINA_MAGIC_STRINGSHARE_HEAD,
|
||||||
|
"Eina Stringshare Head");
|
||||||
|
eina_magic_string_set(EINA_MAGIC_STRINGSHARE_NODE,
|
||||||
|
"Eina Stringshare Node");
|
||||||
|
EINA_MAGIC_SET(share, EINA_MAGIC_STRINGSHARE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ++_eina_stringshare_init_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -237,9 +272,9 @@ eina_stringshare_shutdown()
|
||||||
eina_rbtree_delete(EINA_RBTREE_GET(share->buckets[i]), EINA_RBTREE_FREE_CB(_eina_stringshare_head_free), NULL);
|
eina_rbtree_delete(EINA_RBTREE_GET(share->buckets[i]), EINA_RBTREE_FREE_CB(_eina_stringshare_head_free), NULL);
|
||||||
share->buckets[i] = NULL;
|
share->buckets[i] = NULL;
|
||||||
}
|
}
|
||||||
free(share);
|
MAGIC_FREE(share);
|
||||||
share = NULL;
|
|
||||||
|
|
||||||
|
eina_magic_string_shutdown();
|
||||||
eina_error_shutdown();
|
eina_error_shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,14 +319,19 @@ eina_stringshare_add(const char *str)
|
||||||
ed->hash = hash;
|
ed->hash = hash;
|
||||||
ed->head = NULL;
|
ed->head = NULL;
|
||||||
|
|
||||||
|
EINA_MAGIC_SET(ed, EINA_MAGIC_STRINGSHARE_HEAD);
|
||||||
|
|
||||||
share->buckets[hash_num] = (Eina_Stringshare_Head*) eina_rbtree_inline_insert((Eina_Rbtree*) share->buckets[hash_num],
|
share->buckets[hash_num] = (Eina_Stringshare_Head*) eina_rbtree_inline_insert((Eina_Rbtree*) share->buckets[hash_num],
|
||||||
EINA_RBTREE_GET(ed),
|
EINA_RBTREE_GET(ed),
|
||||||
EINA_RBTREE_CMP_NODE_CB(_eina_stringshare_node), NULL);
|
EINA_RBTREE_CMP_NODE_CB(_eina_stringshare_node), NULL);
|
||||||
|
|
||||||
nel = (Eina_Stringshare_Node*) (ed + 1);
|
nel = (Eina_Stringshare_Node*) (ed + 1);
|
||||||
|
EINA_MAGIC_SET(nel, EINA_MAGIC_STRINGSHARE_NODE);
|
||||||
nel->begin = EINA_TRUE;
|
nel->begin = EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EINA_MAGIC_CHECK_STRINGSHARE_HEAD(ed);
|
||||||
|
|
||||||
for (el = ed->head, tmp = NULL;
|
for (el = ed->head, tmp = NULL;
|
||||||
el && slen != el->length && memcmp(str, (const char*) (el + 1), slen) != 0;
|
el && slen != el->length && memcmp(str, (const char*) (el + 1), slen) != 0;
|
||||||
tmp = el, el = el->next)
|
tmp = el, el = el->next)
|
||||||
|
@ -315,6 +355,8 @@ eina_stringshare_add(const char *str)
|
||||||
nel = malloc(sizeof (Eina_Stringshare_Node) + slen);
|
nel = malloc(sizeof (Eina_Stringshare_Node) + slen);
|
||||||
if (!nel) return NULL;
|
if (!nel) return NULL;
|
||||||
nel->begin = EINA_FALSE;
|
nel->begin = EINA_FALSE;
|
||||||
|
|
||||||
|
EINA_MAGIC_SET(nel, EINA_MAGIC_STRINGSHARE_NODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
nel->references = 1;
|
nel->references = 1;
|
||||||
|
@ -357,6 +399,8 @@ eina_stringshare_del(const char *str)
|
||||||
EINA_RBTREE_CMP_KEY_CB(_eina_stringshare_cmp), NULL);
|
EINA_RBTREE_CMP_KEY_CB(_eina_stringshare_cmp), NULL);
|
||||||
if (!ed) goto on_error;
|
if (!ed) goto on_error;
|
||||||
|
|
||||||
|
EINA_MAGIC_CHECK_STRINGSHARE_HEAD(ed);
|
||||||
|
|
||||||
for (prev = NULL, el = ed->head;
|
for (prev = NULL, el = ed->head;
|
||||||
el && (const char*) (el + 1) != str;
|
el && (const char*) (el + 1) != str;
|
||||||
el = el->next)
|
el = el->next)
|
||||||
|
@ -369,7 +413,8 @@ eina_stringshare_del(const char *str)
|
||||||
{
|
{
|
||||||
if (prev) prev->next = el->next;
|
if (prev) prev->next = el->next;
|
||||||
else ed->head = el->next;
|
else ed->head = el->next;
|
||||||
if (el->begin == EINA_FALSE) free(el);
|
if (el->begin == EINA_FALSE)
|
||||||
|
MAGIC_FREE(el);
|
||||||
|
|
||||||
if (ed->head == NULL)
|
if (ed->head == NULL)
|
||||||
{
|
{
|
||||||
|
@ -377,7 +422,7 @@ eina_stringshare_del(const char *str)
|
||||||
EINA_RBTREE_GET(ed),
|
EINA_RBTREE_GET(ed),
|
||||||
EINA_RBTREE_CMP_NODE_CB(_eina_stringshare_node),
|
EINA_RBTREE_CMP_NODE_CB(_eina_stringshare_node),
|
||||||
NULL);
|
NULL);
|
||||||
free(ed);
|
MAGIC_FREE(ed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ;
|
return ;
|
||||||
|
|
Loading…
Reference in New Issue