summaryrefslogtreecommitdiff
path: root/src/memory.cc
blob: bb0ecb11eec42646bdbc7279eed60811c8dc100b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#ifndef MEMORY_CC
#define MEMORY_CC

#include <mimalloc.h>

#include <cstring>

#include "common.cc"

typedef u8* (*Allocator_Allocate)(u8* self, usize length, usize align);
typedef void (*Allocator_Deallocate)(u8* self, u8* ptr);

struct Allocator {
  u8* self;
  Allocator_Allocate allocate;
  Allocator_Deallocate deallocate;
};

template<typename T>
T* allocate(const Allocator* allocator, usize n) {
  return allocator->allocate(allocator->self, sizeof(T) * n, alignof(T));
}

u8* allocate(const Allocator* allocator, usize size, usize align) {
  return allocator->allocate(allocator->self, size, align);
}

void deallocate(const Allocator* allocator, u8* ptr) {
  allocator->deallocate(allocator->self, ptr);
}

static inline u8* heap_allocate(u8* self, usize size, usize align) {
  (void)self;
  return (u8*)mi_aligned_alloc(align, size);
}

static inline void heap_deallocate(u8* self, u8* ptr) {
  (void)self;
  mi_free(ptr);
}

const Allocator* heap_allocator() {
  thread_local Allocator HEAP_ALLOCATOR = {nullptr, heap_allocate,
                                           heap_deallocate};
  return &HEAP_ALLOCATOR;
}

template <typename T>
bool slice_copy(const Allocator* allocator, const Slice<T>* source,
                Slice<T>* out) {
  T* new_ptr = allocate(allocator, source->size(), alignof(T));
  if (new_ptr == nullptr) return false;

  memcpy((u8*)new_ptr, (u8*)source->ptr, source->length);

  out->length = source->length;
  out->ptr = new_ptr;
  return true;
}

template <typename T>
void slice_deallocate(const Allocator* allocator, Slice<T>* slice) {
  if (slice->ptr == nullptr) return;

  deallocate(allocator, (u8*)slice->ptr);

  slice->ptr = nullptr;
  slice->length = 0;
}

#endif