Commit 77d61533 authored by Kirill Smelkov's avatar Kirill Smelkov

bigfile: Stub for virtmem

This will be the core of virtual memory subsystem. For now we just
define a structure to describe pages of memory and add utility to
allocate address space from OS.
parent e8cea933
/* Wendelin.bigfile | Virtual memory
* Copyright (C) 2014-2015 Nexedi SA and Contributors.
* Kirill Smelkov <kirr@nexedi.com>
*
* This program is free software: you can Use, Study, Modify and Redistribute
* it under the terms of the GNU General Public License version 3, or (at your
* option) any later version, as published by the Free Software Foundation.
*
* You can also Link and Combine this program with other software covered by
* the terms of any of the Open Source Initiative approved licenses and Convey
* the resulting work. Corresponding source of such a combination shall include
* the source code for all other software used.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See COPYING file for full licensing terms.
*/
#include <wendelin/bigfile/virtmem.h>
#include <wendelin/bigfile/ram.h>
#include <sys/mman.h>
#include <errno.h>
/*
* allocate virtual memory address space
* the pages are initially protected to prevent any access
*
* @addr NULL - at anywhere, !NULL - exactly there
* @return !NULL - mapped there NULL - error
*/
void *mem_valloc(void *addr, size_t len)
{
void *a;
a = mmap(addr, len, PROT_NONE,
MAP_PRIVATE | MAP_ANONYMOUS
/* don't try to (pre-)allocate memory - just virtual address space */
| MAP_NORESERVE
| (addr ? MAP_FIXED : 0),
-1, 0);
if (a == MAP_FAILED)
a = NULL;
if (a && addr)
/* verify OS respected our MAP_FIXED request */
BUG_ON(a != addr);
return a;
}
/* like mem_valloc() but allocation must not fail */
void *mem_xvalloc(void *addr, size_t len)
{
void *a;
a = mem_valloc(addr, len);
BUG_ON(!a);
return a;
}
/********************
* Internal helpers *
********************/
static size_t page_size(const Page *page)
{
return page->ramh->ram->pagesize;
}
void page_incref(Page *page)
{
page->refcnt++; // XXX atomically ?
}
void page_decref(Page *page)
{
page->refcnt--; // XXX atomically ?
BUG_ON(page->refcnt < 0);
// TODO if unused delete self && clear pagemap ?
// XXX if dirty -> delete = not ok
}
void *page_mmap(Page *page, void *addr, int prot)
{
RAMH *ramh = page->ramh;
// XXX better call ramh_mmap_page() without tinkering wih ramh_ops?
return ramh->ramh_ops->mmap_page(ramh, page->ramh_pgoffset, addr, prot);
}
#ifndef _WENDELIN_BIGFILE_VIRTMEM_H_
#define _WENDELIN_BIGFILE_VIRTMEM_H_
/* Wendelin.bigfile | Virtual memory
* Copyright (C) 2014-2015 Nexedi SA and Contributors.
* Kirill Smelkov <kirr@nexedi.com>
*
* This program is free software: you can Use, Study, Modify and Redistribute
* it under the terms of the GNU General Public License version 3, or (at your
* option) any later version, as published by the Free Software Foundation.
*
* You can also Link and Combine this program with other software covered by
* the terms of any of the Open Source Initiative approved licenses and Convey
* the resulting work. Corresponding source of such a combination shall include
* the source code for all other software used.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See COPYING file for full licensing terms.
*/
#include <stdint.h>
#include <wendelin/list.h>
typedef struct RAMH RAMH;
/* Page - describes fixed-size item of physical RAM associated with content from file */
enum PageState {
PAGE_EMPTY = 0, /* file content has not been loaded yet */
PAGE_LOADED = 1, /* file content has been loaded and was not modified */
PAGE_DIRTY = 2, /* file content has been loaded and was modified */
};
typedef enum PageState PageState;
struct Page {
PageState state;
/* wrt ram - associated with */
RAMH* ramh;
pgoff_t ramh_pgoffset;
/* in recently-used pages for ramh->ram (ram->lru_list -> _) */
struct list_head lru;
int refcnt; /* each mapping in a vma counts here */
};
typedef struct Page Page;
/************
* Internal *
************/
/* mmap page memory into address space
*
* @addr NULL - mmap somewhere, !NULL - mmap exactly there (MAP_FIXED)
* @return !NULL - mmapped ok there, NULL - error
*
* NOTE to unmap memory either
*
* - use usual munmap(2), or
* - mmap(2) something else in place of mmaped page memory.
*/
void *page_mmap(Page *page, void *addr, int prot);
void page_incref(Page *page);
void page_decref(Page *page);
/* allocate virtual memory address space */
void *mem_valloc(void *addr, size_t len);
void *mem_xvalloc(void *addr, size_t len);
#endif
...@@ -29,6 +29,7 @@ _bigfile = Extension('wendelin.bigfile._bigfile', ...@@ -29,6 +29,7 @@ _bigfile = Extension('wendelin.bigfile._bigfile',
'bigfile/_bigfile.c', 'bigfile/_bigfile.c',
'bigfile/pagefault.c', 'bigfile/pagefault.c',
'bigfile/pagemap.c', 'bigfile/pagemap.c',
'bigfile/virtmem.c',
'lib/bug.c', 'lib/bug.c',
'lib/utils.c', 'lib/utils.c',
], ],
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment