Пример #1
0
        /*
         * Remove the provided entry from whichever list it's currently in. This
         * assumes that the entry is in a list. You don't need to provide the list
         * because the lists are circular, so the list's pointers will automatically
         * be updated if the first or last entries are removed.
         */
        private static void List_remove(List_t *entry)
        {
            List_t *prev = entry->prev;
            List_t *next = entry->next;

            prev->next = next;
            next->prev = prev;
        }
Пример #2
0
        /*
         * Append the provided entry to the end of the list. This assumes the entry
         * isn't in a list already because it overwrites the linked list pointers.
         */
        private static void List_push(List_t *list, List_t *entry)
        {
            List_t *prev = list->prev;

            entry->prev = prev;
            entry->next = list;
            prev->next  = entry;
            list->prev  = entry;
        }
Пример #3
0
        /*
         * Remove and return the first entry in the list or NULL if the list is empty.
         */
        private static List_t *List_pop(List_t *list)
        {
            List_t *back = list->prev;

            if (back == list)
            {
                return(null);
            }
            List_remove(back);
            return(back);
        }
Пример #4
0
        /*
         * This array represents a linearized binary tree of bits. Every possible
         * allocation larger than MIN_ALLOC has a node in this tree (and therefore a
         * bit in this array).
         *
         * Given the index for a node, linearized binary trees allow you to traverse to
         * the parent node or the child nodes just by doing simple arithmetic on the
         * index:
         *
         * - Move to parent:         index = (index - 1) / 2;
         * - Move to left child:     index = index * 2 + 1;
         * - Move to right child:    index = index * 2 + 2;
         * - Move to sibling:        index = ((index - 1) ^ 1) + 1;
         *
         * Each node in this tree can be in one of several states:
         *
         * - UNUSED (both children are UNUSED)
         * - SPLIT (one child is UNUSED and the other child isn't)
         * - USED (neither children are UNUSED)
         *
         * These states take two bits to store. However, it turns out we have enough
         * information to distinguish between UNUSED and USED from context, so we only
         * need to store SPLIT or not, which only takes a single bit.
         *
         * Note that we don't need to store any nodes for allocations of size MIN_ALLOC
         * since we only ever care about parent nodes.
         */
        //static uint8_t node_is_split[(1 << (BUCKET_COUNT - 1)) / 8];
        //protected byte* node_is_split;

        /*
         * This is the starting address of the address range for this allocator. Every
         * returned allocation will be an offset of this pointer from 0 to MAX_ALLOC.
         */
        //void* base_ptr;

        /*
         * This is the maximum address that has ever been used by the allocator. It's
         * used to know when to call "brk" to request more memory from the kernel.
         */
        //void* max_ptr;

        /*
         * Make sure all addresses before "new_value" are valid and can be used. Memory
         * is allocated in a 2gb address range but that memory is not reserved up
         * front. It's only reserved when it's needed by calling this function. This
         * will return false if the memory could not be reserved.
         */
        //bool update_max_ptr(void* new_value)
        //{
        //    if (new_value > max_ptr)
        //    {
        //        if (brk(new_value))
        //        {
        //            return true;
        //        }
        //        max_ptr = new_value;
        //    }
        //    return false;
        //}

        /*
         * Initialize a list to empty. Because these are circular lists, an "empty"
         * list is an entry where both links point to itself. This makes insertion
         * and removal simpler because they don't need any branches.
         */
        private static void List_init(List_t *list)
        {
            list->prev = list;
            list->next = list;
        }