void inplace_lf_queue::enqueue_unsafe(char* c) { // clear the next pointer (*get_next_ptr(c)) = NULL; // swap(tail, c) // tail->next = c; char* prev = c; std::swap(tail, prev); (*get_next_ptr(prev)) = c; }
void enqueue(T* c) { // clear the next pointer (*get_next_ptr(c)) = NULL; // atomically, // swap(tail, c) // tail->next = c; T* prev = c; atomic_exchange(tail, prev); (*get_next_ptr(prev)) = c; asm volatile ("" : : : "memory"); }
void print_list(void *hdrp) { fprintf(stderr, "\n\n"); while (hdrp) { fprintf(stderr, "-------------------\n"); fprintf(stderr, "Block Header: %x, Size = %u, ALLOC Bit = %d\n", hdrp, get_size(hdrp), get_alloc(hdrp)); fprintf(stderr, "Previous Ptr: %x, Next Ptr: %x\n", get_prev_ptr(hdrp), get_next_ptr(hdrp)); hdrp = get_next_ptr(hdrp); } }
int is_in_size_class(void *hdrp, int index) { void *head = free_list_arr[index]; while (head && head != hdrp) { head = get_next_ptr(head); } return head == hdrp ? 1 : 0; }
// O(1) void delete_from_size_class(void *hdrp, int index) { void *head = free_list_arr[index]; #if HEAP_CHECK assert(index >= 0 && index < LEVEL); assert(hdrp); assert(head); assert(is_in_size_class(hdrp, index)); assert(hdrp); int i = 0; for (i = 0; i < LEVEL; ++i) { if (i == index) continue; assert(!is_in_size_class(hdrp, i)); } #endif void *prev_ptr = get_prev_ptr(hdrp); void *next_ptr = get_next_ptr(hdrp); if (!prev_ptr) { // if current node is the firt node free_list_arr[index] = next_ptr; // head = curr_node->next } else { set_next_ptr(prev_ptr, next_ptr); // curr->prev->next = curr_node->next } if (next_ptr) { // if curr_node->next != NULL set_prev_ptr(next_ptr, prev_ptr); // curr_node->next->prev = curr_node->prev } set_prev_ptr(hdrp, NULL); // curr->next = NULL set_next_ptr(hdrp, NULL); // curr->prev = NULL }
void insert_into_size_class(void *hdrp, int index) { #if LIFO_ORDERING set_next_ptr(hdrp, free_list_arr[index]); // hdrp->next = head set_prev_ptr(hdrp, NULL); // hdrp->prev = NULL if (free_list_arr[index]) { // if (head) set_prev_ptr(free_list_arr[index], hdrp); // head->prev = hdrp } free_list_arr[index] = hdrp; // head = hdrp #else // address ordering void *head = free_list_arr[index]; if (!head) { free_list_arr[index] = hdrp; } else if (hdrp < head) { set_next_ptr(hdrp, head); // hdrp->next = head set_prev_ptr(hdrp, NULL); // hdrp->prev = NULL set_prev_ptr(head, hdrp); // head->prev = hdrp free_list_arr[index] = hdrp; // head = hdrp } else { // while (head->next && head->next < hdrp), loop invariant: head < hdrp while (get_next_ptr(head) && get_next_ptr(head) < hdrp) { head = get_next_ptr(head); } set_next_ptr(hdrp, get_next_ptr(head)); // hdrp->next = head->next set_next_ptr(head, hdrp); // head->next = hdrp set_prev_ptr(hdrp, head); // hdrp->prev = head if (get_next_ptr(hdrp)) { // if (hdrp->next) set_prev_ptr(get_next_ptr(hdrp), hdrp); // hdrp->next->prev = hdrp } } #endif }
int segregated_free_list_valid(void) { int i = 0; for (i = 0; i < LEVEL; ++i) { size_t low = index_arr[i]; size_t high = low * 2 - 1; void *head = free_list_arr[i]; while (head) { size_t size = get_size(head); assert(size >= low && size < high); head = get_next_ptr(head); } } }
// linear search void *find_fit(size_t asize) { #if FIRST_FIT int index = find_index(asize); while (index < LEVEL) { void *head = free_list_arr[index]; while (head) { if (get_size(head) >= asize) { return head; } head = get_next_ptr(head); } ++index; } #else int index = find_index(asize); void *ret = NULL; size_t min_size = (1 << 31) - 1; while (index < LEVEL) { void *head = free_list_arr[index]; while (head) { size_t h_size = get_size(head); if (h_size >= asize && h_size < min_size) { ret = head; min_size = h_size; } head = get_next_ptr(head); } if (ret == NULL) { ++index; } else { return ret; } } #endif return NULL; }