eo: add a small object cache to make memory recycling faster.
authorCedric Bail <cedric.bail@samsung.com>
Wed, 11 Sep 2013 02:23:50 +0000 (11:23 +0900)
committerCedric Bail <cedric.bail@samsung.com>
Wed, 11 Sep 2013 02:23:50 +0000 (11:23 +0900)
src/lib/eo/eo.c
src/lib/eo/eo_private.h

index b1f2d15d2ed2a9fa1e007e8fa21f7211fef20bea..835eb861784f63c291396c7eb299e4f4d58f8f08 100644 (file)
@@ -687,6 +687,8 @@ eo_class_funcs_set(Eo_Class *klass_id, const Eo_Op_Func_Description *func_descs)
 static void
 eo_class_free(_Eo_Class *klass)
 {
+   void *object;
+
    if (klass->constructed)
      {
         if (klass->desc->class_destructor)
@@ -695,6 +697,11 @@ eo_class_free(_Eo_Class *klass)
         _dich_func_clean_all(klass);
      }
 
+   EINA_TRASH_CLEAN(&klass->trash, object)
+     free(object);
+
+   eina_lock_free(&klass->trash_lock);
+
    free(klass);
 }
 
@@ -886,6 +893,7 @@ eo_class_new(const Eo_Class_Description *desc, const Eo_Class *parent_id, ...)
 
    klass = calloc(1, _eo_class_sz + extn_sz + mro_sz + mixins_sz);
    EINA_MAGIC_SET(klass, EO_CLASS_EINA_MAGIC);
+   eina_lock_new(&klass->trash_lock);
    klass->parent = parent;
    klass->desc = desc;
    klass->extensions = (const _Eo_Class **) ((char *) klass + _eo_class_sz);
@@ -1073,6 +1081,7 @@ EAPI Eo *
 eo_add_internal(const char *file, int line, const Eo_Class *klass_id, Eo *parent_id, ...)
 {
    Eina_Bool do_err;
+   _Eo *obj;
    _Eo_Class *klass = _eo_class_pointer_get(klass_id);
    EO_MAGIC_RETURN_VAL(klass, EO_CLASS_EINA_MAGIC, NULL);
 
@@ -1087,7 +1096,19 @@ eo_add_internal(const char *file, int line, const Eo_Class *klass_id, Eo *parent
         return NULL;
      }
 
-   _Eo *obj = calloc(1, klass->obj_size);
+   eina_lock_take(&klass->trash_lock);
+   obj = eina_trash_pop(&klass->trash);
+   if (obj)
+     {
+        memset(obj, 0, klass->obj_size);
+        klass->trash_count--;
+     }
+   else
+     {
+        obj = calloc(1, klass->obj_size);
+     }
+   eina_lock_release(&klass->trash_lock);
+
    obj->refcount++;
    obj->klass = klass;
 
index b236b08f8f4cbdd67fcc55a170feab2f47805e8d..591251771ace0cdb771dfa817874d380661db449 100644 (file)
@@ -139,6 +139,11 @@ struct _Eo_Class
 
    const _Eo_Class **mro;
 
+   /* cached object for faster allocation */
+   Eina_Trash  *trash;
+   Eina_Lock    trash_lock;
+   unsigned int trash_count;
+
    unsigned int obj_size; /**< size of an object of this class */
    unsigned int chain_size;
    unsigned int base_id;
@@ -204,6 +209,8 @@ _eo_del_internal(const char *file, int line, _Eo *obj)
 static inline void
 _eo_free(_Eo *obj)
 {
+   _Eo_Class *klass = (_Eo_Class*) obj->klass;
+
 #ifdef EO_DEBUG
    if (obj->datarefcount)
      {
@@ -211,7 +218,19 @@ _eo_free(_Eo *obj)
      }
 #endif
    _eo_id_release(obj->obj_id);
-   free(obj);
+
+   eina_lock_take(&klass->trash_lock);
+   if (klass->trash_count <= 8)
+     {
+        eina_trash_push(&klass->trash, obj);
+        klass->trash_count++;
+        eina_lock_release(&klass->trash_lock);
+     }
+   else
+     {
+        eina_lock_release(&klass->trash_lock);
+        free(obj);
+     }
 }
 
 static inline _Eo *