109 lines
2.1 KiB
109 lines
2.1 KiB
5 years ago
|
/*
|
||
|
sbrk.c - swap memory allocation
|
||
|
Copyright (C) 2019 mittorn
|
||
|
|
||
|
This program is free software: you can redistribute it and/or modify
|
||
|
it under the terms of the GNU General Public License as published by
|
||
|
the Free Software Foundation, either version 3 of the License, or
|
||
|
(at your option) any later version.
|
||
|
|
||
|
This program is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
*/
|
||
|
#define _GNU_SOURCE
|
||
|
#include <dlfcn.h>
|
||
|
#include <sys/mman.h>
|
||
|
#include <unistd.h>
|
||
|
#include <sys/types.h>
|
||
|
#include <fcntl.h>
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <errno.h>
|
||
|
#include <signal.h>
|
||
|
#define _GNU_SOURCE
|
||
|
#include <dlfcn.h>
|
||
|
#include "platform/swap/swap.h"
|
||
|
#include "string.h"
|
||
|
|
||
|
#ifndef XASH_DEFAULT_SWAP_PATH
|
||
|
#define XASH_DEFAULT_SWAP_PATH "/tmp/xash3d-swap"
|
||
|
#endif
|
||
|
#define PAGE_SIZE 4096
|
||
|
static struct sbrk_state_s
|
||
|
{
|
||
|
void *top;
|
||
|
int fd;
|
||
|
size_t size;
|
||
|
size_t prealloc;
|
||
|
pid_t pid;
|
||
|
} s;
|
||
|
|
||
|
static void SWAP_Initialize(void)
|
||
|
{
|
||
|
char *path;
|
||
|
char *prealloc = getenv("SWAP_SIZE");
|
||
|
int fd;
|
||
|
|
||
|
if( s.top )
|
||
|
return;
|
||
|
|
||
|
path = getenv("SWAP_PATH");
|
||
|
if( !path )
|
||
|
path = XASH_DEFAULT_SWAP_PATH;
|
||
|
fd = open( path, O_CREAT|O_RDWR, 0600 );
|
||
|
|
||
|
if( prealloc ) s.prealloc = atoi(prealloc);
|
||
|
else s.prealloc = 128*1024*1024;
|
||
|
s.prealloc &= ~(PAGE_SIZE - 1);
|
||
|
|
||
|
s.fd = fd;
|
||
|
ftruncate( fd, s.prealloc );
|
||
|
s.top = mmap( 0, s.prealloc, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0 );
|
||
|
|
||
|
// space will be freed on exit
|
||
|
//unlink(path);
|
||
|
}
|
||
|
|
||
|
void *SWAP_Sbrk(size_t size)
|
||
|
{
|
||
|
char buf[64];
|
||
|
SWAP_Initialize();
|
||
|
|
||
|
if( size == 0 )
|
||
|
return s.top;
|
||
|
else if( size > 0 )
|
||
|
{
|
||
|
void *res;
|
||
|
|
||
|
//write(1, buf, snprintf(buf, 32, "allocating %d\n", size) );
|
||
|
res = s.top;
|
||
|
s.size += size;
|
||
|
s.top = res + size;
|
||
|
if( s.size + size > s.prealloc )
|
||
|
return (void*)-1;
|
||
|
|
||
|
memset( res, 0, size );
|
||
|
return res;
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
void *res = s.top;
|
||
|
|
||
|
if( -size > s.size )
|
||
|
res = (void*)-1;
|
||
|
else
|
||
|
{
|
||
|
s.top += size;
|
||
|
s.size += size;
|
||
|
//write(1, buf, snprintf(buf, 32, "freed %d\n", -size) );
|
||
|
}
|
||
|
|
||
|
return res;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|