---
# System prepended metadata

title: '`mimalloc` issues'
tags: [Cprogramming]

---

# `mimalloc` issues
## Shared Library On macOS Mojave
```bash
macOS Mojave version 10.14.5 
```
```bash
$ uname -a
Darwin Kernel Version 18.6.0
```
### Add shared library (All of them works on Linux)
```cmake
set (mi_sources
    src/stats.c
    src/os.c
    src/segment.c
    src/page.c
    src/alloc.c
    src/alloc-aligned.c
    src/heap.c
    src/options.c
    src/init.c)
.
.
.
add_library(mimalloc SHARED ${mi_sources})
```
#### test(failed)
```bash
$ ./dynamic-override 
[1]    72000 abort      ./dynamic-override
```
---
```cmake
set (mi_sources SHARED
    src/stats.c
    src/os.c
    src/segment.c
    src/page.c
    src/alloc.c
    src/alloc-aligned.c
    src/heap.c
    src/options.c
    src/init.c)
.
.
.
add_library(mimalloc SHARED ${mi_sources})
```
#### test(success)
```bash
$ ./dynamic-override
heap stats:     peak      total      freed       unit      count  
   elapsed:     0.000 s
   process: user: 0.001 s, system: 0.001 s, faults: 0, reclaims: 405, rss: 848.0 kb
```
---
```cmake
add_library(mimalloc SHARED     
    src/stats.c
    src/os.c
    src/segment.c
    src/page.c
    src/alloc.c
    src/alloc-aligned.c
    src/heap.c
    src/options.c
    src/init.c)
```
#### test(success)
```bash
$ ./dynamic-override
heap stats:     peak      total      freed       unit      count  
   elapsed:     0.000 s
   process: user: 0.001 s, system: 0.001 s, faults: 0, reclaims: 415, rss: 868.0 kb
```

## Add header to usr/local/include (both on linux and macos) (done)

```cmake
install(FILES include/mimalloc.h DESTINATION ${mi_install_dir}/include)
```
`{$mi_install_dir}` = `lib/mimalloc-${mi_version}`

but on [guide](https://github.com/microsoft/mimalloc#macos-linux-bsd-etc)
> install the library and header files in /usr/local/lib and /usr/local/include

which lead to
```bash 
$ gcc -o main -lmimalloc main.c 
main.c:3:10: fatal error: 'mimalloc.h' file not found
#include <mimalloc.h>
         ^~~~~~~~~~~~
1 error generated.
```
solution:
```cmake
install(FILES include/mimalloc.h DESTINATION include)
```

[#89](https://github.com/microsoft/mimalloc/pull/89/files)

## IRI build with Mimalloc
[Full report](https://hackmd.io/@hPMCWajOS-ORQdEEAQ04-w/HywEX8YNH)

### integrate with dltcollab iri (todo)
* efficience comparison
* updaet epic

## Refactor page_queue
* refactor ` mi_page_queue_remove ` to ` mi_page_queue_remove_clear `
    * add ` _mi_page_queue_remove `
    * add ` _mi_page_clear ` 

### _mi_page_queue_remove
```clike
static void _mi_page_queue_remove(mi_page_queue_t* queue, mi_page_t* page) {
  if (page->prev != NULL) page->prev->next = page->next;
  if (page->next != NULL) page->next->prev = page->prev;
  if (page == queue->last)  queue->last = page->prev;
  if (page == queue->first) {
    queue->first = page->next;
    // update first
    mi_heap_t* heap = page->heap;
    mi_assert_internal(mi_heap_contains_queue(heap, queue));
    mi_heap_queue_first_update(heap,queue);
  }
  page->heap->page_count--;
}
```
### _mi_page_clear
```clike
static void _mi_page_clear(mi_page_t* page) {
  page->next = NULL;
  page->prev = NULL;
  page->heap = NULL;
  page->flags.in_full = false;
}
```
### mi_page_queue_remove_clear
```clike 
static void mi_page_queue_remove_clear(mi_page_queue_t* queue, mi_page_t* page) {
  mi_assert_internal(page != NULL);
  mi_assert_expensive(mi_page_queue_contains(queue, page));
  mi_assert_internal(page->block_size == queue->block_size || (page->block_size > MI_LARGE_SIZE_MAX && mi_page_queue_is_huge(queue))  || (page->flags.in_full && mi_page_queue_is_full(queue)));
  _mi_page_queue_remove(queue, page);
  _mi_page_clear(page);
}
```
---
* refactor ` mi_page_queue_push `
    * add ` _mi_page_queue_add `
* refactor ` mi_page_queue_enqueue_from `
    * using ` _mi_page_queue_add ` ` _mi_page_queue_remove `
### _mi_page_queue_add
```clike
static void _mi_page_queue_add(mi_page_queue_t* queue,mi_page_t* page) {
  page->flags.in_full = mi_page_queue_is_full(queue);
  page->next = queue->first;
  page->prev = NULL;
  if (queue->first != NULL) {
    mi_assert_internal(queue->first->prev == NULL);
    queue->first->prev = page;
  }
  else {
    queue->last = page;
  }
  queue->first = page;
}
```

### mi_page_queue_push
```clike 
static void mi_page_queue_push(mi_heap_t* heap, mi_page_queue_t* queue, mi_page_t* page) {
  mi_assert_internal(page->heap == NULL);
  mi_assert_internal(!mi_page_queue_contains(queue, page));
  mi_assert_internal(page->block_size == queue->block_size || (page->block_size > MI_LARGE_SIZE_MAX && mi_page_queue_is_huge(queue)) || (page->flags.in_full && mi_page_queue_is_full(queue)));

  page->heap = heap;
  heap->page_count++;

  _mi_page_queue_add(queue, page);
  // update direct
  mi_heap_queue_first_update(heap, queue);
  
}
```

### mi_page_queue_enqueue_from
```clike
static void mi_page_queue_enqueue_from(mi_page_queue_t* to, mi_page_queue_t* from, mi_page_t* page) {
  mi_assert_internal(page != NULL);
  mi_assert_expensive(mi_page_queue_contains(from, page));
  mi_assert_expensive(!mi_page_queue_contains(to, page));
  mi_assert_internal(page->block_size == to->block_size ||
                     (page->block_size > MI_LARGE_SIZE_MAX && (mi_page_queue_is_huge(to) || mi_page_queue_is_full(to))) ||
                      (page->block_size == from->block_size && mi_page_queue_is_full(to)));

  _mi_page_queue_remove(from, page);
  mi_page_queue_push(page->heap, to, page);
}
```
---

### Breaking long assertion lines


### todo
* add internal functions to internal function header file
for instance `mimalloc-internal.h`
```clike
// "page.c"
void*      _mi_malloc_generic(mi_heap_t* heap, size_t size)  mi_attr_noexcept mi_attr_malloc;

void       _mi_page_retire(mi_page_t* page);                                  // free the page if there are no other pages with many free blocks
void       _mi_page_unfull(mi_page_t* page);
void       _mi_page_free(mi_page_t* page, mi_page_queue_t* pq, bool force);   // free the page
void       _mi_page_abandon(mi_page_t* page, mi_page_queue_t* pq);            // abandon the page, to be picked up by another thread...
void       _mi_heap_delayed_free(mi_heap_t* heap);

void       _mi_page_use_delayed_free(mi_page_t* page, mi_delayed_t delay);
size_t     _mi_page_queue_append(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_queue_t* append);
void       _mi_deferred_free(mi_heap_t* heap, bool force);

void       _mi_page_free_collect(mi_page_t* page);
void       _mi_page_reclaim(mi_heap_t* heap, mi_page_t* page);   // callback from segments

size_t     _mi_bin_size(uint8_t bin);           // for stats
uint8_t    _mi_bin(size_t size);                // for stats
uint8_t    _mi_bsr(uintptr_t x);                // bit-scan-right, used on BSD in "os.c"
```

* rename queue


### reference
[linux kernel list.h](https://github.com/torvalds/linux/blob/master/include/linux/list.h)
[linux kernel coding style](https://www.kernel.org/doc/html/v4.10/process/coding-style.html#functions)
###### tags: `Cprogramming`