master
stbi_alloc.h
1#ifndef STBI_ALLOC_H
2#define STBI_ALLOC_H
3
4#include <sys/mman.h>
5#include <unistd.h>
6#include <string.h>
7#include <stdint.h>
8
9#define STBI_MALLOC(sz) stbi_mmap_alloc(sz)
10#define STBI_FREE(p) stbi_mmap_free(p)
11#define STBI_REALLOC(p,sz) stbi_mmap_realloc(p,sz)
12
13static void *stbi_mmap_alloc(size_t sz)
14{
15 if (sz == 0) return NULL;
16 long page = sysconf(_SC_PAGESIZE);
17 size_t mapsz = ((sz + page) & ~(page - 1)) + page;
18 void *p = mmap(NULL, mapsz, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
19 if (p == MAP_FAILED) return NULL;
20 *(size_t*)p = mapsz;
21 return (char*)p + page;
22}
23
24static void stbi_mmap_free(void *p)
25{
26 if (!p) return;
27 long page = sysconf(_SC_PAGESIZE);
28 void *base = (char*)p - page;
29 size_t mapsz = *(size_t*)base;
30 munmap(base, mapsz);
31}
32
33static void *stbi_mmap_realloc(void *p, size_t newsz)
34{
35 if (!p) return stbi_mmap_alloc(newsz);
36 if (newsz == 0) {
37 stbi_mmap_free(p);
38 return NULL;
39 }
40 long page = sysconf(_SC_PAGESIZE);
41 void *base = (char*)p - page;
42 size_t old_mapsz = *(size_t*)base;
43 size_t oldsz = old_mapsz - page;
44 void *newp = stbi_mmap_alloc(newsz);
45 if (!newp) return p;
46 memcpy(newp, p, oldsz < newsz ? oldsz : newsz);
47 munmap(base, old_mapsz);
48 return newp;
49}
50
51#endif