77 lines
2.0 KiB
C
77 lines
2.0 KiB
C
#include <sys/mman.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
#include <strings.h> /* for bzero() */
|
|
#include "util.h"
|
|
#include "chunk.h"
|
|
#include "lj_mm.h"
|
|
#include "ljmm_conf.h"
|
|
|
|
#define SIZE_1MB ((uint)0x100000)
|
|
#define SIZE_1GB ((uint)0x40000000)
|
|
|
|
/* If we end up allocating a chunk no larger than this size, we might as well
|
|
* pull the plug, and give up for good.
|
|
*/
|
|
#define MEM_TOO_SMALL (SIZE_1MB * 8)
|
|
|
|
static lm_chunk_t big_chunk;
|
|
|
|
lm_chunk_t*
|
|
lm_alloc_chunk (void) {
|
|
if (big_chunk.base)
|
|
return &big_chunk;
|
|
|
|
uintptr_t cur_brk = (uintptr_t)sbrk(0);
|
|
uintptr_t page_sz = sysconf(_SC_PAGESIZE);
|
|
cur_brk = (page_sz - 1 + cur_brk) & ~(page_sz - 1);
|
|
|
|
uint avail = LJMM_AS_UPBOUND - ((intptr_t)cur_brk);
|
|
avail = avail & ~(page_sz - 1);
|
|
if (avail < MEM_TOO_SMALL) {
|
|
/* We can achieve almost nothing with 1MB, might as well bail out. */
|
|
return 0;
|
|
}
|
|
|
|
uintptr_t chunk = (uintptr_t)
|
|
mmap((void*)cur_brk, avail, PROT_READ|PROT_WRITE,
|
|
MAP_PRIVATE | MAP_32BIT | MAP_ANONYMOUS, -1, 0);
|
|
|
|
if (!chunk)
|
|
return NULL;
|
|
|
|
madvise((void*)chunk, avail, MADV_DONTNEED|MADV_DONTDUMP);
|
|
|
|
big_chunk.base = (char*)chunk;
|
|
big_chunk.start = (char*)chunk;
|
|
big_chunk.alloc_size = avail;
|
|
big_chunk.usable_size = avail;
|
|
big_chunk.page_size = page_sz;
|
|
big_chunk.page_num = big_chunk.usable_size / page_sz;
|
|
|
|
return &big_chunk;
|
|
}
|
|
|
|
void
|
|
lm_free_chunk(void) {
|
|
ENTER_MUTEX
|
|
if (big_chunk.base) {
|
|
munmap(big_chunk.base, big_chunk.alloc_size);
|
|
bzero(&big_chunk, sizeof(big_chunk));
|
|
}
|
|
LEAVE_MUTEX
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
void
|
|
lm_dump_chunk (FILE* f) {
|
|
uint num_page = big_chunk.usable_size / sysconf(_SC_PAGESIZE);
|
|
|
|
fprintf(f, "Base:%8p, alloc-size :%fG, usage-start:%8p, usage-size %fG (%u pages)\n",
|
|
big_chunk.base, big_chunk.alloc_size / ((float)SIZE_1GB),
|
|
big_chunk.start, big_chunk.usable_size / ((float)SIZE_1GB),
|
|
num_page);
|
|
}
|
|
#endif
|