[svn:parrot] r47141 - branches/gc_massacre/src/gc

bacek at svn.parrot.org bacek at svn.parrot.org
Sun May 30 09:38:51 UTC 2010


Author: bacek
Date: Sun May 30 09:38:51 2010
New Revision: 47141
URL: https://trac.parrot.org/parrot/changeset/47141

Log:
Implement linked-list. Not tested

Modified:
   branches/gc_massacre/src/gc/list.c
   branches/gc_massacre/src/gc/list.h

Modified: branches/gc_massacre/src/gc/list.c
==============================================================================
--- branches/gc_massacre/src/gc/list.c	Sun May 30 09:38:27 2010	(r47140)
+++ branches/gc_massacre/src/gc/list.c	Sun May 30 09:38:51 2010	(r47141)
@@ -33,6 +33,83 @@
 
 */
 
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+struct Linked_List*
+Parrot_gc_allocate_linked_list(SHIM_INTERP)
+{
+    Linked_List *res = (Linked_List*)mem_sys_allocate_zeroed(sizeof (Linked_List));
+    return res;
+}
+
+PARROT_EXPORT
+void
+Parrot_gc_destroy_linked_list(SHIM_INTERP, ARGMOD(Linked_List* list))
+{
+    mem_sys_free(list);
+}
+
+PARROT_EXPORT
+void
+Parrot_gc_list_append(SHIM_INTERP, ARGMOD(Linked_List *list), ARGMOD(List_Item_Header *item))
+{
+    /* First item */
+    if (!list->first) {
+        list->first = list->last = item;
+        item->prev = item->next = NULL;
+    }
+    else {
+        item->prev = list->last;
+        item->next = NULL;
+        list->last = item;
+    }
+    list->count++;
+}
+
+PARROT_EXPORT
+void
+Parrot_gc_list_prepend(SHIM_INTERP, ARGMOD(Linked_List *list), ARGMOD(List_Item_Header *item))
+{
+    /* First item */
+    if (!list->first) {
+        list->first = list->last = item;
+        item->prev = item->next = NULL;
+    }
+    else {
+        item->prev = NULL;
+        item->next = list->first;
+        list->first = item;
+    }
+    list->count++;
+}
+
+PARROT_EXPORT
+void
+Parrot_gc_list_remove(SHIM_INTERP, ARGMOD(Linked_List *list), ARGMOD(List_Item_Header *item))
+{
+    /* First item */
+    if (list->first == item) {
+        list->first = list->first->next;
+        /* Not the last one */
+        if (list->first) {
+            list->first->prev = NULL;
+        }
+    }
+    else if (list->last == item) {
+        list->last = list->last->prev;
+        /* It' can't be last item. */
+        list->last->next = NULL;
+    }
+    else {
+        List_Item_Header *prev = item->prev;
+        List_Item_Header *next = item->next;
+        prev->next = next;
+        next->prev = prev;
+        item->prev = item->next = NULL;
+    }
+}
+
+
 /*
 
 =back

Modified: branches/gc_massacre/src/gc/list.h
==============================================================================
--- branches/gc_massacre/src/gc/list.h	Sun May 30 09:38:27 2010	(r47140)
+++ branches/gc_massacre/src/gc/list.h	Sun May 30 09:38:51 2010	(r47141)
@@ -15,10 +15,81 @@
 #ifndef PARROT_GC_LIST_H_GUARD
 #define PARROT_GC_LIST_H_GUARD
 
+/* Allocatable objects has headers to use in linked lists */
+typedef struct List_Item_Header {
+    struct List_Item_Header *prev;
+    struct List_Item_Header *next;
+} List_Item_Header;
+
+/* Double-linked list. */
+/* N.B. List doesn't _own_ items */
+typedef struct Linked_List {
+    struct List_Item_Header *first;
+    struct List_Item_Header *last;
+
+    /* Cache object count in list. We use it very often */
+    size_t count;
+} Linked_List;
+
+/* Such headers allocated in front of real objects. */
+/* There is helper macros to convert to/from real objects */
+#define Obj2LLH(p) (List_Item_Header* ((char*)(p) - sizeof (List_Item_Header))
+#define LLH2Obj_typed(p, type), ((type*)((char*)(p) + sizeof (List_Item_Header))
+#define LLH2Obj(p) LLH2Obj_typed(p, void)
+
 
 /* HEADERIZER BEGIN: src/gc/list.c */
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 
+PARROT_EXPORT
+PARROT_CANNOT_RETURN_NULL
+struct Linked_List* Parrot_gc_allocate_linked_list(SHIM_INTERP);
+
+PARROT_EXPORT
+void Parrot_gc_destroy_linked_list(SHIM_INTERP, ARGMOD(Linked_List* list))
+        __attribute__nonnull__(2)
+        FUNC_MODIFIES(* list);
+
+PARROT_EXPORT
+void Parrot_gc_list_append(SHIM_INTERP,
+    ARGMOD(Linked_List *list),
+    ARGMOD(List_Item_Header *item))
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3)
+        FUNC_MODIFIES(*list)
+        FUNC_MODIFIES(*item);
+
+PARROT_EXPORT
+void Parrot_gc_list_prepend(SHIM_INTERP,
+    ARGMOD(Linked_List *list),
+    ARGMOD(List_Item_Header *item))
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3)
+        FUNC_MODIFIES(*list)
+        FUNC_MODIFIES(*item);
+
+PARROT_EXPORT
+void Parrot_gc_list_remove(SHIM_INTERP,
+    ARGMOD(Linked_List *list),
+    ARGMOD(List_Item_Header *item))
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3)
+        FUNC_MODIFIES(*list)
+        FUNC_MODIFIES(*item);
+
+#define ASSERT_ARGS_Parrot_gc_allocate_linked_list \
+     __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
+#define ASSERT_ARGS_Parrot_gc_destroy_linked_list __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(list))
+#define ASSERT_ARGS_Parrot_gc_list_append __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(list) \
+    , PARROT_ASSERT_ARG(item))
+#define ASSERT_ARGS_Parrot_gc_list_prepend __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(list) \
+    , PARROT_ASSERT_ARG(item))
+#define ASSERT_ARGS_Parrot_gc_list_remove __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+       PARROT_ASSERT_ARG(list) \
+    , PARROT_ASSERT_ARG(item))
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
 /* HEADERIZER END: src/gc/list.c */
 


More information about the parrot-commits mailing list