forked from enlightenment/efl
fix eina_cow issues. Closes T581, T527
This commit is contained in:
parent
1cad4c2afe
commit
f45618d15b
|
@ -80,7 +80,6 @@ struct _Eina_Cow_GC
|
||||||
Eina_Cow_Ptr *ref;
|
Eina_Cow_Ptr *ref;
|
||||||
const void **dst;
|
const void **dst;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _Eina_Cow
|
struct _Eina_Cow
|
||||||
{
|
{
|
||||||
#ifdef EINA_COW_MAGIC_ON
|
#ifdef EINA_COW_MAGIC_ON
|
||||||
|
@ -91,7 +90,7 @@ struct _Eina_Cow
|
||||||
Eina_Hash *match;
|
Eina_Hash *match;
|
||||||
|
|
||||||
Eina_Mempool *pool;
|
Eina_Mempool *pool;
|
||||||
const void *default_value;
|
const Eina_Cow_Data *default_value;
|
||||||
|
|
||||||
unsigned int struct_size;
|
unsigned int struct_size;
|
||||||
unsigned int total_size;
|
unsigned int total_size;
|
||||||
|
@ -123,7 +122,7 @@ typedef int (*Eina_Cow_Hash)(const void *, int);
|
||||||
(((Eina_Cow_Ptr *)d) - 1)
|
(((Eina_Cow_Ptr *)d) - 1)
|
||||||
|
|
||||||
#define EINA_COW_DATA_GET(d) \
|
#define EINA_COW_DATA_GET(d) \
|
||||||
((unsigned char *)(d + 1))
|
(((Eina_Cow_Ptr *)d) + 1)
|
||||||
|
|
||||||
static int _eina_cow_log_dom = -1;
|
static int _eina_cow_log_dom = -1;
|
||||||
|
|
||||||
|
@ -142,8 +141,9 @@ static int _eina_cow_log_dom = -1;
|
||||||
#endif
|
#endif
|
||||||
#define DBG(...) EINA_LOG_DOM_DBG(_eina_cow_log_dom, __VA_ARGS__)
|
#define DBG(...) EINA_LOG_DOM_DBG(_eina_cow_log_dom, __VA_ARGS__)
|
||||||
|
|
||||||
|
|
||||||
static Eina_Mempool *gc_pool = NULL;
|
static Eina_Mempool *gc_pool = NULL;
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
_eina_cow_hash_gen(const void *key, int key_length,
|
_eina_cow_hash_gen(const void *key, int key_length,
|
||||||
Eina_Cow_Hash hash,
|
Eina_Cow_Hash hash,
|
||||||
|
@ -184,7 +184,7 @@ static int current_cow_size = 0;
|
||||||
static unsigned int
|
static unsigned int
|
||||||
_eina_cow_length(const void *key EINA_UNUSED)
|
_eina_cow_length(const void *key EINA_UNUSED)
|
||||||
{
|
{
|
||||||
/* nasty hack, has only gc need to access the hash, he will be in charge
|
/* nasty hack, since only gc needs to access the hash, it will be in charge
|
||||||
of that global. access to the hash should be considered global.
|
of that global. access to the hash should be considered global.
|
||||||
*/
|
*/
|
||||||
return current_cow_size;
|
return current_cow_size;
|
||||||
|
@ -254,26 +254,25 @@ _eina_cow_togc_add(Eina_Cow *cow,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_eina_cow_gc(Eina_Cow *cow, Eina_Cow_Ptr *ref,
|
_eina_cow_gc(Eina_Cow *cow, Eina_Cow_GC *gc)
|
||||||
const Eina_Cow_Data **dst,
|
|
||||||
void *data)
|
|
||||||
{
|
{
|
||||||
void *match;
|
Eina_Cow_Data *data;
|
||||||
|
Eina_Cow_Data *match;
|
||||||
|
|
||||||
ref->togc = EINA_FALSE;
|
data = EINA_COW_DATA_GET(gc->ref);
|
||||||
|
|
||||||
current_cow_size = cow->struct_size;
|
current_cow_size = cow->struct_size;
|
||||||
match = eina_hash_find(cow->match, data);
|
match = eina_hash_find(cow->match, data);
|
||||||
if (match)
|
if (match)
|
||||||
{
|
{
|
||||||
ref = EINA_COW_PTR_GET(match);
|
Eina_Cow_Ptr *ref = EINA_COW_PTR_GET(match);
|
||||||
#ifndef NVALGRIND
|
#ifndef NVALGRIND
|
||||||
VALGRIND_MAKE_MEM_DEFINED(ref, sizeof (*ref));
|
VALGRIND_MAKE_MEM_DEFINED(ref, sizeof (*ref));
|
||||||
#endif
|
#endif
|
||||||
ref->refcount++;
|
ref->refcount += gc->ref->refcount;
|
||||||
|
|
||||||
eina_cow_free(cow, dst);
|
*gc->dst = match;
|
||||||
*dst = match;
|
eina_cow_free(cow, (const Eina_Cow_Data**) &data);
|
||||||
|
|
||||||
#ifndef NVALGRIND
|
#ifndef NVALGRIND
|
||||||
VALGRIND_MAKE_MEM_NOACCESS(ref, sizeof (*ref));
|
VALGRIND_MAKE_MEM_NOACCESS(ref, sizeof (*ref));
|
||||||
|
@ -282,7 +281,9 @@ _eina_cow_gc(Eina_Cow *cow, Eina_Cow_Ptr *ref,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
eina_hash_direct_add(cow->match, data, data);
|
eina_hash_direct_add(cow->match, data, data);
|
||||||
ref->hashed = EINA_TRUE;
|
gc->ref->hashed = EINA_TRUE;
|
||||||
|
gc->ref->togc = EINA_FALSE;
|
||||||
|
eina_hash_del(cow->togc, &gc->ref, gc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,7 +367,7 @@ eina_cow_add(const char *name, unsigned int struct_size, unsigned int step, cons
|
||||||
_eina_cow_cmp,
|
_eina_cow_cmp,
|
||||||
_eina_cow_hash32,
|
_eina_cow_hash32,
|
||||||
NULL,
|
NULL,
|
||||||
6);
|
6);
|
||||||
#endif
|
#endif
|
||||||
if (gc)
|
if (gc)
|
||||||
cow->togc = eina_hash_pointer_new(_eina_cow_gc_free);
|
cow->togc = eina_hash_pointer_new(_eina_cow_gc_free);
|
||||||
|
@ -453,7 +454,7 @@ eina_cow_write(Eina_Cow *cow,
|
||||||
const Eina_Cow_Data * const *data)
|
const Eina_Cow_Data * const *data)
|
||||||
{
|
{
|
||||||
Eina_Cow_Ptr *ref;
|
Eina_Cow_Ptr *ref;
|
||||||
void *r;
|
Eina_Cow_Data *r;
|
||||||
|
|
||||||
#ifdef EINA_COW_MAGIC_ON
|
#ifdef EINA_COW_MAGIC_ON
|
||||||
EINA_COW_MAGIC_CHECK(cow);
|
EINA_COW_MAGIC_CHECK(cow);
|
||||||
|
@ -484,8 +485,8 @@ eina_cow_write(Eina_Cow *cow,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (cow->togc)
|
if (cow->togc)
|
||||||
_eina_cow_hash_del(cow, *data, ref);
|
_eina_cow_hash_del(cow, *data, ref);
|
||||||
|
|
||||||
#ifndef NVALGRIND
|
#ifndef NVALGRIND
|
||||||
VALGRIND_MAKE_MEM_NOACCESS(ref, sizeof (*ref));
|
VALGRIND_MAKE_MEM_NOACCESS(ref, sizeof (*ref));
|
||||||
|
@ -509,7 +510,7 @@ eina_cow_write(Eina_Cow *cow,
|
||||||
|
|
||||||
r = EINA_COW_DATA_GET(ref);
|
r = EINA_COW_DATA_GET(ref);
|
||||||
memcpy(r, *data, cow->struct_size);
|
memcpy(r, *data, cow->struct_size);
|
||||||
*((void**) data) = r;
|
*((Eina_Cow_Data**) data) = r;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
#ifndef NVALGRIND
|
#ifndef NVALGRIND
|
||||||
|
@ -602,8 +603,8 @@ eina_cow_gc(Eina_Cow *cow)
|
||||||
{
|
{
|
||||||
Eina_Cow_GC *gc;
|
Eina_Cow_GC *gc;
|
||||||
Eina_Iterator *it;
|
Eina_Iterator *it;
|
||||||
void *data;
|
|
||||||
Eina_Bool r;
|
Eina_Bool r;
|
||||||
|
Eina_Cow_Ptr *ref;
|
||||||
|
|
||||||
EINA_COW_MAGIC_CHECK(cow);
|
EINA_COW_MAGIC_CHECK(cow);
|
||||||
|
|
||||||
|
@ -613,22 +614,20 @@ eina_cow_gc(Eina_Cow *cow)
|
||||||
it = eina_hash_iterator_data_new(cow->togc);
|
it = eina_hash_iterator_data_new(cow->togc);
|
||||||
r = eina_iterator_next(it, (void**) &gc);
|
r = eina_iterator_next(it, (void**) &gc);
|
||||||
eina_iterator_free(it);
|
eina_iterator_free(it);
|
||||||
|
|
||||||
if (!r) return EINA_FALSE; /* Something did go wrong here */
|
if (!r) return EINA_FALSE; /* Something did go wrong here */
|
||||||
|
|
||||||
/* Do handle hash and all funky merge think here */
|
/* Do handle hash and all funky merge thing here */
|
||||||
data = EINA_COW_DATA_GET(gc->ref);
|
ref = gc->ref;
|
||||||
|
|
||||||
#ifndef NVALGRIND
|
#ifndef NVALGRIND
|
||||||
VALGRIND_MAKE_MEM_DEFINED(gc->ref, sizeof (Eina_Cow_Ptr));
|
VALGRIND_MAKE_MEM_DEFINED(ref, sizeof (*ref));
|
||||||
#endif
|
#endif
|
||||||
_eina_cow_gc(cow, gc->ref, gc->dst, data);
|
_eina_cow_gc(cow, gc);
|
||||||
#ifndef NVALGRIND
|
#ifndef NVALGRIND
|
||||||
VALGRIND_MAKE_MEM_NOACCESS(gc->ref, sizeof (Eina_Cow_Ptr));
|
VALGRIND_MAKE_MEM_NOACCESS(ref, sizeof (*ref));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
eina_hash_del(cow->togc, &gc->ref, gc);
|
|
||||||
|
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,9 +56,9 @@ typedef void Eina_Cow_Data;
|
||||||
*
|
*
|
||||||
* @param name The name of this pool, used for debug.
|
* @param name The name of this pool, used for debug.
|
||||||
* @param struct_size The size of the object from this pool.
|
* @param struct_size The size of the object from this pool.
|
||||||
* @param step How many object to allocate when the pool get empty.
|
* @param step How many objects to allocate when the pool gets empty.
|
||||||
* @param default_value The default value returned by this pool.
|
* @param default_value The default value returned by this pool.
|
||||||
* @param gc Is it possible to run the garbage collection on this pool.
|
* @param gc Is it possible to run garbage collection on this pool.
|
||||||
* @return a valid new Eina_Cow or @c NULL on error.
|
* @return a valid new Eina_Cow or @c NULL on error.
|
||||||
*/
|
*/
|
||||||
EAPI Eina_Cow *eina_cow_add(const char *name, unsigned int struct_size, unsigned int step, const void *default_value, Eina_Bool gc) EINA_WARN_UNUSED_RESULT;
|
EAPI Eina_Cow *eina_cow_add(const char *name, unsigned int struct_size, unsigned int step, const void *default_value, Eina_Bool gc) EINA_WARN_UNUSED_RESULT;
|
||||||
|
@ -71,7 +71,7 @@ EAPI Eina_Cow *eina_cow_add(const char *name, unsigned int struct_size, unsigned
|
||||||
EAPI void eina_cow_del(Eina_Cow *cow);
|
EAPI void eina_cow_del(Eina_Cow *cow);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return a initialized pointer to the pool.
|
* @brief Return an initialized pointer from the pool.
|
||||||
* @param cow The pool to take things from.
|
* @param cow The pool to take things from.
|
||||||
*/
|
*/
|
||||||
EAPI const Eina_Cow_Data *eina_cow_alloc(Eina_Cow *cow) EINA_WARN_UNUSED_RESULT;
|
EAPI const Eina_Cow_Data *eina_cow_alloc(Eina_Cow *cow) EINA_WARN_UNUSED_RESULT;
|
||||||
|
@ -98,8 +98,8 @@ EAPI void *eina_cow_write(Eina_Cow *cow,
|
||||||
/**
|
/**
|
||||||
* @brief Set back a pointer into read only.
|
* @brief Set back a pointer into read only.
|
||||||
* @param cow The pool the pointer come from.
|
* @param cow The pool the pointer come from.
|
||||||
* @param src The read only version of the pointer.
|
* @param dst The read only version of the pointer.
|
||||||
* @param data The pointer to which data where written to.
|
* @param data The pointer to which data was written to.
|
||||||
*
|
*
|
||||||
* NOTE: this function is not thread safe, be careful.
|
* NOTE: this function is not thread safe, be careful.
|
||||||
*/
|
*/
|
||||||
|
@ -118,13 +118,13 @@ EAPI void eina_cow_memcpy(Eina_Cow *cow,
|
||||||
const Eina_Cow_Data *src);
|
const Eina_Cow_Data *src);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Try to find entry that do have the same content and update them.
|
* @brief Try to find entries that have the same content and update them.
|
||||||
* @param cow The cow to try to compact.
|
* @param cow The cow to try to compact.
|
||||||
* @return EINA_TRUE if something was compacted, EINA_FALSE if nothing was.
|
* @return EINA_TRUE if something was compacted, EINA_FALSE if nothing was.
|
||||||
*
|
*
|
||||||
* There is no guaranty in the time it will require, but should remain low.
|
* There is no guaranty in the time it will require, but should remain low.
|
||||||
* It does run a hash function on all possible common structure trying to
|
* It does run a hash function on all possible common structures trying to
|
||||||
* find the one that match and merge then into one pointer.
|
* find the one that match and merge them into one pointer.
|
||||||
*/
|
*/
|
||||||
EAPI Eina_Bool eina_cow_gc(Eina_Cow *cow);
|
EAPI Eina_Bool eina_cow_gc(Eina_Cow *cow);
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ EAPI Eina_Bool eina_cow_gc(Eina_Cow *cow);
|
||||||
* @param Write The name of the variable where to put the writeable pointer to.
|
* @param Write The name of the variable where to put the writeable pointer to.
|
||||||
* @since 1.8.0
|
* @since 1.8.0
|
||||||
*
|
*
|
||||||
* Be careful this macro open a C scope that it expect to be closed by
|
* Be careful this macro opens a C scope that is expected to be closed by
|
||||||
* EINA_COW_WRITE_END().
|
* EINA_COW_WRITE_END().
|
||||||
*/
|
*/
|
||||||
#define EINA_COW_WRITE_BEGIN(Cow, Read, Write_Type, Write) \
|
#define EINA_COW_WRITE_BEGIN(Cow, Read, Write_Type, Write) \
|
||||||
|
|
Loading…
Reference in New Issue