# `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`