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