Xash3D FWGS engine.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 lines
2.1 KiB

/*
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;
}
}