summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkira TAGOH <akira@tagoh.org>2011-02-25 20:33:55 +0900
committerAkira TAGOH <akira@tagoh.org>2011-02-25 20:33:55 +0900
commit9fa2ab19f5e2566b5d5a6ad846c2770f19b9a723 (patch)
treec948cc30d71eca5604d9dddd524412a13c5e37fa
parent25253b0af1b9fb822b64b52f4c0df3c3b3503ad1 (diff)
hgmem APIs cleanup
-rw-r--r--hieroglyph/hgmem.c115
-rw-r--r--hieroglyph/hgmem.h11
-rw-r--r--hieroglyph/hgsnapshot.c117
-rw-r--r--hieroglyph/hgsnapshot.h16
-rw-r--r--hieroglyph/hgvm.c20
5 files changed, 126 insertions, 153 deletions
diff --git a/hieroglyph/hgmem.c b/hieroglyph/hgmem.c
index b49a4fc..025c4ab 100644
--- a/hieroglyph/hgmem.c
+++ b/hieroglyph/hgmem.c
@@ -396,121 +396,6 @@ hg_mem_spool_get_used_size(hg_mem_t *mem)
return mem->data->used_size;
}
-/**
- * hg_mem_save_snapshot:
- * @mem:
- *
- * FIXME
- *
- * Returns:
- */
-hg_mem_snapshot_data_t *
-hg_mem_save_snapshot(hg_mem_t *mem)
-{
- hg_mem_snapshot_data_t *retval;
-
- hg_return_val_if_fail (mem != NULL, NULL, HG_e_VMerror);
- hg_return_val_if_fail (mem->allocator != NULL, NULL, HG_e_VMerror);
- hg_return_val_if_fail (mem->allocator->save_snapshot != NULL, NULL, HG_e_VMerror);
- hg_return_val_if_fail (mem->data != NULL, NULL, HG_e_VMerror);
-
- /* clean up to obtain the certain information to be restored */
- if (hg_mem_spool_run_gc(mem) < 0)
- return NULL;
-
- retval = mem->allocator->save_snapshot(mem->data);
- if (retval) {
- retval->total_size = mem->data->total_size;
- retval->used_size = mem->data->used_size;
- }
-
- return retval;
-}
-
-/**
- * hg_mem_restore_snapshot:
- * @mem:
- * @snapshot:
- * @func:
- * @data:
- *
- * FIXME
- *
- * Returns:
- */
-hg_bool_t
-hg_mem_restore_snapshot(hg_mem_t *mem,
- hg_mem_snapshot_data_t *snapshot,
- hg_gc_func_t func,
- hg_pointer_t data)
-{
- hg_bool_t retval = FALSE;
-
- hg_return_val_if_fail (mem != NULL, FALSE, HG_e_VMerror);
- hg_return_val_if_fail (mem->allocator != NULL, FALSE, HG_e_VMerror);
- hg_return_val_if_fail (mem->allocator->restore_snapshot != NULL, FALSE, HG_e_VMerror);
- hg_return_val_if_fail (mem->data != NULL, FALSE, HG_e_VMerror);
- hg_return_val_if_fail (mem->reference_table == NULL, FALSE, HG_e_VMerror);
-
- mem->reference_table = g_hash_table_new(g_direct_hash, g_direct_equal);
- if (!func(mem, data))
- goto finalize;
-
- retval = mem->allocator->restore_snapshot(mem->data,
- snapshot,
- mem->reference_table);
-
- finalize:
- g_hash_table_destroy(mem->reference_table);
- mem->reference_table = NULL;
-
- return retval;
-}
-
-/**
- * hg_mem_restore_mark:
- * @mem:
- * @qdata:
- *
- * FIXME
- */
-void
-hg_mem_restore_mark(hg_mem_t *mem,
- hg_quark_t qdata)
-{
- hg_return_if_fail (mem != NULL, HG_e_VMerror);
-
- if (qdata == Qnil)
- return;
- if (mem->reference_table == NULL)
- return;
-
- hg_return_if_fail (hg_quark_has_mem_id(qdata, mem->id), HG_e_VMerror);
-
- g_hash_table_insert(mem->reference_table,
- HGQUARK_TO_POINTER (hg_quark_get_value(qdata)),
- HGQUARK_TO_POINTER (hg_quark_get_value(qdata)));
-}
-
-/**
- * hg_mem_snapshot_free:
- * @mem:
- * @snapshot:
- *
- * FIXME
- */
-void
-hg_mem_snapshot_free(hg_mem_t *mem,
- hg_mem_snapshot_data_t *snapshot)
-{
- hg_return_if_fail (mem != NULL, HG_e_VMerror);
- hg_return_if_fail (mem->allocator != NULL, HG_e_VMerror);
- hg_return_if_fail (mem->allocator->destroy_snapshot != NULL, HG_e_VMerror);
- hg_return_if_fail (mem->data != NULL, HG_e_VMerror);
-
- mem->allocator->destroy_snapshot(mem->data, snapshot);
-}
-
/** memory management **/
/**
diff --git a/hieroglyph/hgmem.h b/hieroglyph/hgmem.h
index d4123dc..bccc94d 100644
--- a/hieroglyph/hgmem.h
+++ b/hieroglyph/hgmem.h
@@ -85,17 +85,6 @@ hg_size_t hg_mem_spool_run_gc (hg_mem_t *mem);
hg_usize_t hg_mem_spool_get_total_size (hg_mem_t *mem);
hg_usize_t hg_mem_spool_get_used_size (hg_mem_t *mem);
-
-hg_allocator_snapshot_data_t *hg_mem_save_snapshot (hg_mem_t *mem);
-hg_bool_t hg_mem_restore_snapshot (hg_mem_t *mem,
- hg_allocator_snapshot_data_t *snapshot,
- hg_gc_func_t func,
- hg_pointer_t data);
-void hg_mem_restore_mark (hg_mem_t *mem,
- hg_quark_t qdata);
-void hg_mem_snapshot_free (hg_mem_t *mem,
- hg_allocator_snapshot_data_t *snapshot);
-
/* memory management */
hg_quark_t hg_mem_alloc (hg_mem_t *mem,
hg_usize_t size,
diff --git a/hieroglyph/hgsnapshot.c b/hieroglyph/hgsnapshot.c
index 030e239..fdc563e 100644
--- a/hieroglyph/hgsnapshot.c
+++ b/hieroglyph/hgsnapshot.c
@@ -25,7 +25,10 @@
#include "config.h"
#endif
+/* XXX: GLib is needed for GHashTable */
+#include <glib.h>
#include "hgmem.h"
+#include "hgmem-private.h"
#include "hgsnapshot.h"
#include "hgsnapshot.proto.h"
@@ -33,6 +36,7 @@
struct _hg_snapshot_t {
hg_object_t o;
hg_mem_snapshot_data_t *snapshot;
+ GHashTable *ref_table;
};
HG_DEFINE_VTABLE (snapshot);
@@ -61,12 +65,21 @@ static void
_hg_object_snapshot_free(hg_object_t *object)
{
hg_snapshot_t *snapshot = (hg_snapshot_t *)object;
+ hg_mem_t *mem;
hg_return_if_fail (object->type == HG_TYPE_SNAPSHOT, HG_e_typecheck);
+ hg_return_if_fail (snapshot->o.mem != NULL, HG_e_VMerror);
- if (snapshot->snapshot)
- hg_mem_snapshot_free(snapshot->o.mem,
- snapshot->snapshot);
+ mem = snapshot->o.mem;
+
+ hg_return_if_fail (mem->allocator != NULL, HG_e_VMerror);
+ hg_return_if_fail (mem->allocator->destroy_snapshot != NULL, HG_e_VMerror);
+ hg_return_if_fail (mem->data != NULL, HG_e_VMerror);
+
+ if (snapshot->snapshot) {
+ mem->allocator->destroy_snapshot(mem->data,
+ snapshot->snapshot);
+ }
}
static hg_quark_t
@@ -150,13 +163,29 @@ hg_snapshot_new(hg_mem_t *mem,
hg_bool_t
hg_snapshot_save(hg_snapshot_t *snapshot)
{
+ hg_mem_t *mem;
+
hg_return_val_if_fail (snapshot != NULL, FALSE, HG_e_typecheck);
+ hg_return_val_if_fail (snapshot->o.mem != NULL, FALSE, HG_e_VMerror);
- snapshot->snapshot = hg_mem_save_snapshot(snapshot->o.mem);
- if (snapshot->snapshot == NULL)
+ mem = snapshot->o.mem;
+
+ hg_return_val_if_fail (mem != NULL, FALSE, HG_e_VMerror);
+ hg_return_val_if_fail (mem->allocator != NULL, FALSE, HG_e_VMerror);
+ hg_return_val_if_fail (mem->allocator->save_snapshot != NULL, FALSE, HG_e_VMerror);
+ hg_return_val_if_fail (mem->data != NULL, FALSE, HG_e_VMerror);
+
+ /* clean up to obtain the certain information to be restored */
+ if (hg_mem_spool_run_gc(mem) < 0)
return FALSE;
- return TRUE;
+ snapshot->snapshot = mem->allocator->save_snapshot(mem->data);
+ if (!snapshot->snapshot) {
+ snapshot->snapshot->total_size = hg_mem_spool_get_total_size(mem);
+ snapshot->snapshot->used_size = hg_mem_spool_get_used_size(mem);
+ }
+
+ return snapshot->snapshot ? TRUE : FALSE;
}
/**
@@ -170,23 +199,83 @@ hg_snapshot_save(hg_snapshot_t *snapshot)
* Returns:
*/
hg_bool_t
-hg_snapshot_restore(hg_snapshot_t *snapshot,
- hg_gc_func_t func,
- hg_pointer_t data)
+hg_snapshot_restore(hg_snapshot_t *snapshot,
+ hg_restore_prep_func_t func,
+ hg_pointer_t data)
{
- hg_bool_t retval;
+ hg_bool_t retval = FALSE;
+ hg_mem_t *mem;
+ static volatile hg_int_t is_running = 0;
+ hg_int_t old_val;
hg_return_val_if_fail (snapshot != NULL, FALSE, HG_e_typecheck);
hg_return_val_if_fail (snapshot->snapshot != NULL, FALSE, HG_e_VMerror);
+ hg_return_val_if_fail (snapshot->o.mem != NULL, FALSE, HG_e_VMerror);
+
+ mem = snapshot->o.mem;
+
+ hg_return_val_if_fail (mem->allocator != NULL, FALSE, HG_e_VMerror);
+ hg_return_val_if_fail (mem->allocator->restore_snapshot != NULL, FALSE, HG_e_VMerror);
+ hg_return_val_if_fail (mem->data != NULL, FALSE, HG_e_VMerror);
+ hg_return_val_if_fail (mem->reference_table == NULL, FALSE, HG_e_VMerror);
+
+ retry:
+ old_val = g_atomic_int_get(&is_running);
+ if (old_val > 0) {
+ hg_critical("Unable to restore the snapshot during restoring");
+ hg_error_return (HG_STATUS_FAILED, HG_e_VMerror);
+ }
+ if (!g_atomic_int_compare_and_exchange(&is_running, old_val, old_val + 1))
+ goto retry;
hg_mem_spool_run_gc(snapshot->o.mem);
- retval = hg_mem_restore_snapshot(snapshot->o.mem,
- snapshot->snapshot,
- func,
- data);
+
+ snapshot->ref_table = g_hash_table_new(g_direct_hash, g_direct_equal);
+ if (!func(snapshot, data))
+ goto finalize;
+
+ retval = mem->allocator->restore_snapshot(mem->data,
+ snapshot->snapshot,
+ snapshot->ref_table);
if (retval) {
snapshot->snapshot = NULL;
}
+ finalize:
+ g_hash_table_destroy(snapshot->ref_table);
+ snapshot->ref_table = NULL;
+
+ retry2:
+ old_val = g_atomic_int_get(&is_running);
+ if (!g_atomic_int_compare_and_exchange(&is_running, old_val, old_val - 1))
+ goto retry2;
return retval;
}
+
+/**
+ * hg_snapshot_add_ref:
+ * @snapshot:
+ * @qdata:
+ *
+ * FIXME
+ */
+void
+hg_snapshot_add_ref(hg_snapshot_t *snapshot,
+ hg_quark_t qdata)
+{
+ hg_int_t id;
+
+ hg_return_if_fail (snapshot != NULL, HG_e_typecheck);
+ hg_return_if_fail (snapshot->o.type == HG_TYPE_SNAPSHOT, HG_e_typecheck);
+
+ if (qdata == Qnil ||
+ snapshot->ref_table == NULL)
+ return;
+
+ id = hg_mem_get_id(snapshot->o.mem);
+ hg_return_if_fail (hg_quark_has_mem_id(qdata, id), HG_e_VMerror);
+
+ g_hash_table_insert(snapshot->ref_table,
+ HGQUARK_TO_POINTER (hg_quark_get_value(qdata)),
+ HGQUARK_TO_POINTER (hg_quark_get_value(qdata)));
+}
diff --git a/hieroglyph/hgsnapshot.h b/hieroglyph/hgsnapshot.h
index 11b6a52..7d39dbc 100644
--- a/hieroglyph/hgsnapshot.h
+++ b/hieroglyph/hgsnapshot.h
@@ -40,14 +40,18 @@ HG_BEGIN_DECLS
typedef struct _hg_snapshot_t hg_snapshot_t;
+typedef hg_bool_t (* hg_restore_prep_func_t) (hg_snapshot_t *snapshot,
+ hg_pointer_t user_data);
hg_object_vtable_t *hg_object_snapshot_get_vtable(void) HG_GNUC_CONST;
-hg_quark_t hg_snapshot_new (hg_mem_t *mem,
- hg_pointer_t *ret);
-hg_bool_t hg_snapshot_save (hg_snapshot_t *snapshot);
-hg_bool_t hg_snapshot_restore (hg_snapshot_t *snapshot,
- hg_gc_func_t func,
- hg_pointer_t data);
+hg_quark_t hg_snapshot_new (hg_mem_t *mem,
+ hg_pointer_t *ret);
+hg_bool_t hg_snapshot_save (hg_snapshot_t *snapshot);
+hg_bool_t hg_snapshot_restore (hg_snapshot_t *snapshot,
+ hg_restore_prep_func_t func,
+ hg_pointer_t data);
+void hg_snapshot_add_ref (hg_snapshot_t *snapshot,
+ hg_quark_t qdata);
HG_END_DECLS
diff --git a/hieroglyph/hgvm.c b/hieroglyph/hgvm.c
index 8e5fc53..c1c553f 100644
--- a/hieroglyph/hgvm.c
+++ b/hieroglyph/hgvm.c
@@ -738,20 +738,21 @@ _hg_vm_restore_mark_traverse(hg_mem_t *mem,
{
hg_uint_t id = hg_quark_get_mem_id(qdata);
hg_mem_t *m = hg_mem_spool_get(id);
+ hg_snapshot_t *snapshot = (hg_snapshot_t *)data;
if (m == NULL) {
hg_warning("No memory spool found: %d", id);
hg_errno = HG_ERROR_ (HG_STATUS_FAILED, HG_e_VMerror);
return FALSE;
}
- hg_mem_restore_mark(m, qdata);
+ hg_snapshot_add_ref(snapshot, qdata);
return TRUE;
}
static hg_bool_t
-_hg_vm_restore_mark(hg_mem_t *mem,
- hg_pointer_t data)
+_hg_vm_restore_mark(hg_snapshot_t *snapshot,
+ hg_pointer_t data)
{
hg_vm_t *vm = (hg_vm_t *)data;
hg_usize_t i;
@@ -759,7 +760,7 @@ _hg_vm_restore_mark(hg_mem_t *mem,
for (i = 0; i <= HG_VM_STACK_DSTACK; i++) {
hg_stack_foreach(vm->stacks[i],
_hg_vm_restore_mark_traverse,
- vm, FALSE);
+ snapshot, FALSE);
if (!HG_ERROR_IS_SUCCESS0 ())
return FALSE;
}
@@ -2338,11 +2339,16 @@ hg_vm_startjob(hg_vm_t *vm,
/* XXX: restore memory */
if (encapsulated) {
- hg_mem_snapshot_data_t *gsnap = hg_mem_save_snapshot(vm->mem[HG_VM_MEM_GLOBAL]);
- hg_mem_snapshot_data_t *lsnap = hg_mem_save_snapshot(vm->mem[HG_VM_MEM_LOCAL]);
+ hg_snapshot_t *gsnap, *lsnap;
+ hg_quark_t qg = hg_snapshot_new(vm->mem[HG_VM_MEM_GLOBAL], (hg_pointer_t *)&gsnap);
+ hg_quark_t ql = hg_snapshot_new(vm->mem[HG_VM_MEM_LOCAL], (hg_pointer_t *)&lsnap);
- gsnap = lsnap;
+ hg_snapshot_save(gsnap);
+ hg_snapshot_save(lsnap);
/* XXX: save memory */
+
+ _HG_VM_UNLOCK (vm, qg);
+ _HG_VM_UNLOCK (vm, ql);
}
/* change the default memory */