Loading...
Searching...
No Matches
vspace::internals Namespace Reference

## Data Structures

class | FastLock
struct | ProcessInfo
struct | MetaPage
struct | ProcessChannel
struct | Block
struct | VSeg
struct | VMem
struct | refcount_t
class | Mutex

## Typedefs

typedef size_t | segaddr_t
typedef size_t | vaddr_t
typedef int | ipc_signal_t

## Enumerations

enum | SignalState { Waiting = 0 , Pending = 1 , Accepted = 2 }

## Functions

static void | lock_allocator ()
static void | unlock_allocator ()
static void | print_freelists ()
void | vmem_free (vaddr_t vaddr)
vaddr_t | vmem_alloc (size_t size)
void | init_flock_struct (struct flock &lock_info, size_t offset, size_t len, bool lock)
void | lock_file (int fd, size_t offset, size_t len)
void | unlock_file (int fd, size_t offset, size_t len)
void | lock_metapage ()
void | unlock_metapage ()
void | init_metapage (bool create)
static void | lock_process (int processno)
static void | unlock_process (int processno)
static ProcessInfo & | process_info (int processno)
bool | send_signal (int processno, ipc_signal_t sig, bool lock)
ipc_signal_t | check_signal (bool resume, bool lock)
void | accept_signals ()
ipc_signal_t | wait_signal (bool lock)
void | drop_pending_signals ()
Block * | block_ptr (vaddr_t vaddr)
static int | find_level (size_t size)
static segaddr_t | find_buddy (segaddr_t addr, int level)
static vaddr_t | allocated_ptr_to_vaddr (void *ptr)

## Variables

size_t | config [4] = { METABLOCK_SIZE, MAX_PROCESS, SEGMENT_SIZE, MAX_SEGMENTS }
const segaddr_t | SEGADDR_NULL = ~(segaddr_t) 0
const vaddr_t | VADDR_NULL = ~(segaddr_t) 0
static const int | MAX_PROCESS = 64
static const size_t | METABLOCK_SIZE = 128 * 1024
static const int | LOG2_SEGMENT_SIZE = 28
static const int | LOG2_MAX_SEGMENTS = 10
static const size_t | MAX_SEGMENTS = 1 << LOG2_MAX_SEGMENTS
static const size_t | SEGMENT_SIZE = 1 << LOG2_SEGMENT_SIZE
static const size_t | SEGMENT_MASK = (SEGMENT_SIZE - 1)
static VMem & | vmem = VMem::vmem_global

## Data Structure Documentation

## vspace::internals::ProcessInfo

struct vspace::internals::ProcessInfo

Definition at line 1499 of file vspace.h.

Data Fields
pid_t | pid |
ipc_signal_t | signal |
SignalState | sigstate |

## vspace::internals::MetaPage

struct vspace::internals::MetaPage

Definition at line 1508 of file vspace.h.

Data Fields
FastLock | allocator_lock |
size_t | config_header[4] |
vaddr_t | freelist[LOG2_SEGMENT_SIZE+1] |
ProcessInfo | process_info[MAX_PROCESS] |
int | segment_count |

## vspace::internals::ProcessChannel

struct vspace::internals::ProcessChannel

Definition at line 1525 of file vspace.h.

Data Fields
int | fd_read |
int | fd_write |

## Typedef Documentation

## ipc_signal_t

typedef int vspace::internals::ipc_signal_t

Definition at line 1481 of file vspace.h.

## segaddr_t

typedef size_t vspace::internals::segaddr_t

Definition at line 1412 of file vspace.h.

## vaddr_t

typedef size_t vspace::internals::vaddr_t

Definition at line 1414 of file vspace.h.

## Enumeration Type Documentation

## SignalState

enum vspace::internals::SignalState

Enumerator
Waiting |
Pending |
Accepted |

Definition at line 1493 of file vspace.h.

{
Waiting = 0,
Pending = 1,
Accepted = 2,
};
vspace::internals::Accepted
@ Accepted
Definition vspace.h:1496
vspace::internals::Pending
@ Pending
Definition vspace.h:1495
vspace::internals::Waiting
@ Waiting
Definition vspace.h:1494

## Function Documentation

## accept_signals()

void vspace::internals::accept_signals | ( |  | ) |

Definition at line 1069 of file vspace.cc.

{
lock_process(vmem.current_process);
process_info(vmem.current_process).sigstate = Waiting;
unlock_process(vmem.current_process);
}
vspace::internals::process_info
static ProcessInfo & process_info(int processno)
Definition vspace.cc:963
vspace::internals::unlock_process
static void unlock_process(int processno)
Definition vspace.cc:957
vspace::internals::ProcessInfo::sigstate
SignalState sigstate
Definition vspace.h:1501
vspace::internals::lock_process
static void lock_process(int processno)
Definition vspace.cc:951
vspace::internals::vmem
static VMem & vmem
Definition vspace.h:1635

## allocated_ptr_to_vaddr()

vaddr_t vspace::internals::allocated_ptr_to_vaddr | ( | void * | ptr | ) |

inline static

Definition at line 1697 of file vspace.h.

{
char *addr = (char *) ptr - sizeof(Block);
vaddr_t info = ((Block *) addr)->prev;
int seg = info & (MAX_SEGMENTS - 1);
unsigned char *segstart = vmem.segments[seg].base;
size_t offset = (unsigned char *) ptr - segstart;
return (seg << LOG2_SEGMENT_SIZE) | offset;
}
offset
STATIC_VAR int offset
Definition janet.cc:29
info
#define info
Definition libparse.cc:1256
vspace::internals::vaddr_t
size_t vaddr_t
Definition vspace.h:1414
vspace::internals::MAX_SEGMENTS
static const size_t MAX_SEGMENTS
Definition vspace.h:1423
vspace::internals::LOG2_SEGMENT_SIZE
static const int LOG2_SEGMENT_SIZE
Definition vspace.h:1421
vspace::internals::Block
Definition vspace.h:1529

## block_ptr()

Block * vspace::internals::block_ptr | ( | vaddr_t | vaddr | ) |

inline

Definition at line 1637 of file vspace.h.

{
return vmem.block_ptr(vaddr);
}

## check_signal()

ipc_signal_t vspace::internals::check_signal | ( | bool | resume,
|  | bool | lock )

Definition at line 990 of file vspace.cc.

{
ipc_signal_t result;
if (lock)
lock_process(vmem.current_process);
SignalState sigstate = process_info(vmem.current_process).sigstate;
switch (sigstate) {
case Waiting:
case Pending: {
int fd = vmem.channels[vmem.current_process].fd_read;
char buf[1];
if (lock && sigstate == Waiting) {
unlock_process(vmem.current_process);
loop
{
#if defined(HAVE_POLL) && !defined(__APPLE__)
// fd is restricted on OsX by ulimit "file descriptors" (256)
pollfd pfd;
pfd.fd = fd;
pfd.events = POLLIN;
int rv = poll(&pfd, 1, 500000); /* msec*/
#else
// fd is restricted to <=1024
fd_set set;
FD_ZERO(&set); /* clear the set */
FD_SET(fd, &set); /* add our file descriptor to the set */
struct timeval timeout;
timeout.tv_sec = 500;
timeout.tv_usec = 0;
int rv = si_select(fd + 1, &set, NULL, NULL, &timeout);
#endif
if (rv== -1) continue; /* an error occurred */
if (rv== 0) break; /* timeout */
while(read(fd, buf, 1)!=1) {}
break;
}
lock_process(vmem.current_process);
} else {
loop
{
#if defined(HAVE_POLL) && !defined(__APPLE__)
// fd is restricted on OsX by ulimit "file descriptors" (256)
pollfd pfd;
pfd.fd = fd;
pfd.events = POLLIN;
int rv = poll(&pfd, 1, 500000); /* msec*/
#else
// fd is restricted to <=1024
fd_set set;
FD_ZERO(&set); /* clear the set */
FD_SET(fd, &set); /* add our file descriptor to the set */
struct timeval timeout;
timeout.tv_sec = 500;
timeout.tv_usec = 0;
int rv = si_select(fd + 1, &set, NULL, NULL, &timeout);
#endif
if (rv== -1) continue; /* an error occurred */
if (rv== 0) break;/* timeout */
while(read(fd, buf, 1)!=1) {}
break;
}
}
result = process_info(vmem.current_process).signal;
process_info(vmem.current_process).sigstate
= resume ? Waiting : Accepted;
if (lock)
unlock_process(vmem.current_process);
break;
}
case Accepted:
result = process_info(vmem.current_process).signal;
if (resume)
process_info(vmem.current_process).sigstate = Waiting;
if (lock)
unlock_process(vmem.current_process);
break;
}
return result;
}
result
return result
Definition facAbsBiFact.cc:76
vspace::internals::SignalState
SignalState
Definition vspace.h:1493
vspace::internals::ipc_signal_t
int ipc_signal_t
Definition vspace.h:1481
vspace::internals::ProcessInfo::signal
ipc_signal_t signal
Definition vspace.h:1502
NULL
#define NULL
Definition omList.c:12
read
int status read
Definition si_signals.h:69
fd
int status int fd
Definition si_signals.h:69
buf
int status int void * buf
Definition si_signals.h:69
loop
#define loop
Definition structs.h:71
vspace::internals::VMem::current_process
int current_process
Definition vspace.h:1592

## drop_pending_signals()

void vspace::internals::drop_pending_signals | ( |  | ) |

## find_buddy()

segaddr_t vspace::internals::find_buddy | ( | segaddr_t | addr,
|  | int | level )

inline static

Definition at line 1690 of file vspace.h.

{
return addr ^ (1 << level);
}
level
int level(const CanonicalForm &f)
Definition canonicalform.h:331

## find_level()

int vspace::internals::find_level | ( | size_t | size | ) |

inline static

Definition at line 1681 of file vspace.h.

{
int level = 0;
while ((1 << (level + 8)) <= size)
level += 8;
while ((1 << level) < size)
level++;
return level;
}
size
int size(const CanonicalForm &f, const Variable &v)
int size ( const CanonicalForm & f, const Variable & v )
Definition cf_ops.cc:600

## init_flock_struct()

void vspace::internals::init_flock_struct | ( | struct flock & | lock_info,
|  | size_t | offset,
|  | size_t | len,
|  | bool | lock )

Definition at line 904 of file vspace.cc.

{
lock_info.l_start = offset;
lock_info.l_len = len;
lock_info.l_pid = 0;
lock_info.l_type = lock ? F_WRLCK : F_UNLCK;
lock_info.l_whence = SEEK_SET;
}
SEEK_SET
#define SEEK_SET
Definition mod2.h:115

## init_metapage()

void vspace::internals::init_metapage | ( | bool | create | ) |

Definition at line 933 of file vspace.cc.

{
if (create)
ftruncate(vmem.fd, METABLOCK_SIZE);
vmem.metapage = (MetaPage *) mmap(
NULL, METABLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, vmem.fd, 0);
if (create) {
std::memcpy(vmem.metapage->config_header, config, sizeof(config));
for (int i = 0; i <= LOG2_SEGMENT_SIZE; i++) {
vmem.metapage->freelist[i] = VADDR_NULL;
}
vmem.metapage->segment_count = 0;
vmem.metapage->allocator_lock = FastLock(metapageaddr(allocator_lock));
} else {
assert(std::memcmp(vmem.metapage->config_header, config,
sizeof(config)) != 0);
}
}
i
int i
Definition cfEzgcd.cc:132
create
NodeM * create()
Definition janet.cc:757
vspace::internals::VADDR_NULL
const vaddr_t VADDR_NULL
Definition vspace.h:1417
vspace::internals::MetaPage::allocator_lock
FastLock allocator_lock
Definition vspace.h:1510
vspace::internals::MetaPage::config_header
size_t config_header[4]
Definition vspace.h:1509
vspace::internals::METABLOCK_SIZE
static const size_t METABLOCK_SIZE
Definition vspace.h:1420
vspace::internals::MetaPage::segment_count
int segment_count
Definition vspace.h:1512
vspace::internals::config
size_t config[4]
Definition vspace.cc:619
vspace::internals::MetaPage
Definition vspace.h:1508
vspace::FastLock
internals::Mutex FastLock
Definition vspace.h:2340
vspace::internals::VMem::metapage
MetaPage * metapage
Definition vspace.h:1589
assert
#define assert(A)
Definition svd_si.h:3
metapageaddr
#define metapageaddr(field)
Definition vspace.cc:626

## lock_allocator()

void vspace::internals::lock_allocator | ( |  | ) |

static

Definition at line 766 of file vspace.cc.

{
vmem.metapage->allocator_lock.lock();
}

## lock_file()

void vspace::internals::lock_file | ( | int | fd,
|  | size_t | offset,
|  | size_t | len )

Definition at line 913 of file vspace.cc.

{
struct flock lock_info;
init_flock_struct(lock_info, offset, len, true);
fcntl(fd, F_SETLKW, &lock_info);
}
vspace::internals::init_flock_struct
void init_flock_struct(struct flock &lock_info, size_t offset, size_t len, bool lock)
Definition vspace.cc:904

## lock_metapage()

void vspace::internals::lock_metapage | ( |  | ) |

Definition at line 925 of file vspace.cc.

{
lock_file(vmem.fd, 0);
}
vspace::internals::lock_file
void lock_file(int fd, size_t offset, size_t len)
Definition vspace.cc:913

## lock_process()

void vspace::internals::lock_process | ( | int | processno | ) |

static

Definition at line 951 of file vspace.cc.

{
lock_file(vmem.fd,
metapageaddr(process_info)
+ sizeof(ProcessInfo) * vmem.current_process);
}
vspace::internals::ProcessInfo
Definition vspace.h:1499

## print_freelists()

void vspace::internals::print_freelists | ( |  | ) |

static

Definition at line 774 of file vspace.cc.

{
for (int i = 0; i <= LOG2_SEGMENT_SIZE; i++) {
vaddr_t vaddr = vmem.freelist[i];
if (vaddr != VADDR_NULL) {
std::printf("%2d: %ld", i, (long)vaddr);
vaddr_t prev = block_ptr(vaddr)->prev;
if (prev != VADDR_NULL) {
std::printf("(%ld)", (long)prev);
}
assert(block_ptr(vaddr)->prev == VADDR_NULL);
for (;;) {
vaddr_t last_vaddr = vaddr;
Block *block = block_ptr(vaddr);
vaddr = block->next;
if (vaddr == VADDR_NULL)
break;
std::printf(" -> %ld", (long)vaddr);
vaddr_t prev = block_ptr(vaddr)->prev;
if (prev != last_vaddr) {
std::printf("(%ld)", (long)prev);
}
}
std::printf("\n");
}
}
std::fflush(stdout);
}
vspace::internals::block_ptr
Block * block_ptr(vaddr_t vaddr)
Definition vspace.h:1637
block
#define block
Definition scanner.cc:646
vspace::internals::Block::prev
vaddr_t prev
Definition vspace.h:1540

## process_info()

ProcessInfo & vspace::internals::process_info | ( | int | processno | ) |

static

Definition at line 963 of file vspace.cc.

{
return vmem.metapage->process_info[processno];
}

## send_signal()

bool vspace::internals::send_signal | ( | int | processno,
|  | ipc_signal_t | sig,
|  | bool | lock )

Definition at line 967 of file vspace.cc.

{
if (lock)
lock_process(processno);
if (process_info(processno).sigstate != Waiting) {
unlock_process(processno);
return false;
}
if (processno == vmem.current_process) {
process_info(processno).sigstate = Accepted;
process_info(processno).signal = sig;
} else {
process_info(processno).sigstate = Pending;
process_info(processno).signal = sig;
int fd = vmem.channels[processno].fd_write;
char buf[1] = { 0 };
while (write(fd, buf, 1) != 1) {
}
}
if (lock)
unlock_process(processno);
return true;
}
vspace::internals::ProcessChannel::fd_write
int fd_write
Definition vspace.h:1526
vspace::internals::VMem::channels
ProcessChannel channels[MAX_PROCESS]
Definition vspace.h:1595

## unlock_allocator()

void vspace::internals::unlock_allocator | ( |  | ) |

static

Definition at line 770 of file vspace.cc.

{
vmem.metapage->allocator_lock.unlock();
}

## unlock_file()

void vspace::internals::unlock_file | ( | int | fd,
|  | size_t | offset,
|  | size_t | len )

Definition at line 919 of file vspace.cc.

{
struct flock lock_info;
init_flock_struct(lock_info, offset, len, false);
fcntl(fd, F_SETLKW, &lock_info);
}

## unlock_metapage()

void vspace::internals::unlock_metapage | ( |  | ) |

Definition at line 929 of file vspace.cc.

{
unlock_file(vmem.fd, 0);
}
vspace::internals::unlock_file
void unlock_file(int fd, size_t offset, size_t len)
Definition vspace.cc:919

## unlock_process()

void vspace::internals::unlock_process | ( | int | processno | ) |

static

Definition at line 957 of file vspace.cc.

{
unlock_file(vmem.fd,
metapageaddr(process_info)
+ sizeof(ProcessInfo) * vmem.current_process);
}

## vmem_alloc()

vaddr_t vspace::internals::vmem_alloc | ( | size_t | size | ) |

Definition at line 854 of file vspace.cc.

{
lock_allocator();
#if defined(__GNUC__) && (__GNUC__>11)
size_t alloc_size = size + (sizeof(vaddr_t)*2);
#else
size_t alloc_size = size + offsetof(Block, data);
#endif
int level = find_level(alloc_size);
int flevel = level;
while (flevel < LOG2_SEGMENT_SIZE && vmem.freelist[flevel] == VADDR_NULL)
flevel++;
if (vmem.freelist[flevel] == VADDR_NULL) {
vmem.add_segment();
}
vmem.ensure_is_mapped(vmem.freelist[flevel]);
while (flevel > level) {
// get and split a block
vaddr_t blockaddr = vmem.freelist[flevel];
assert((blockaddr & ((1 << flevel) - 1)) == 0);
Block *block = vmem.block_ptr(blockaddr);
vmem.freelist[flevel] = block->next;
if (vmem.freelist[flevel] != VADDR_NULL)
vmem.block_ptr(vmem.freelist[flevel])->prev = VADDR_NULL;
vaddr_t blockaddr2 = blockaddr + (1 << (flevel - 1));
Block *block2 = vmem.block_ptr(blockaddr2);
flevel--;
block2->next = vmem.freelist[flevel];
block2->prev = blockaddr;
block->next = blockaddr2;
block->prev = VADDR_NULL;
// block->prev == VADDR_NULL already.
vmem.freelist[flevel] = blockaddr;
}
assert(vmem.freelist[level] != VADDR_NULL);
Block *block = vmem.block_ptr(vmem.freelist[level]);
vaddr_t vaddr = vmem.freelist[level];
#if defined(__GNUC__) && (__GNUC__>11)
vaddr_t result = vaddr + (sizeof(vaddr_t)*2);
#else
vaddr_t result = vaddr + offsetof(Block, data);
#endif
vmem.freelist[level] = block->next;
if (block->next != VADDR_NULL)
vmem.block_ptr(block->next)->prev = VADDR_NULL;
block->mark_as_allocated(vaddr, level);
unlock_allocator();
memset(block->data, 0, size);
return result;
}
vspace::internals::lock_allocator
static void lock_allocator()
Definition vspace.cc:766
vspace::internals::find_level
static int find_level(size_t size)
Definition vspace.h:1681
vspace::internals::unlock_allocator
static void unlock_allocator()
Definition vspace.cc:770
vspace::internals::Block::next
vaddr_t next
Definition vspace.h:1541
vspace::internals::VMem::ensure_is_mapped
void ensure_is_mapped(vaddr_t vaddr)
Definition vspace.h:1615
vspace::internals::VMem::block_ptr
Block * block_ptr(vaddr_t vaddr)
Definition vspace.h:1610
vspace::internals::VMem::freelist
vaddr_t * freelist
Definition vspace.h:1593

## vmem_free()

void vspace::internals::vmem_free | ( | vaddr_t | vaddr | ) |

Definition at line 802 of file vspace.cc.

{
lock_allocator();
#if defined(__GNUC__) && (__GNUC__>11)
vaddr -= (sizeof(vaddr_t)*2);
#else
vaddr -= offsetof(Block, data);
#endif
vmem.ensure_is_mapped(vaddr);
size_t segno = vmem.segment_no(vaddr);
VSeg seg = vmem.segment(vaddr);
segaddr_t addr = vmem.segaddr(vaddr);
int level = seg.block_ptr(addr)->level();
assert(!seg.is_free(addr));
while (level < LOG2_SEGMENT_SIZE) {
segaddr_t buddy = find_buddy(addr, level);
Block *block = seg.block_ptr(buddy);
// is buddy free and at the same level?
if (!block->is_free() || block->level() != level)
break;
// remove buddy from freelist.
Block *prev = vmem.block_ptr(block->prev);
Block *next = vmem.block_ptr(block->next);
block->data[0] = level;
if (prev) {
assert(prev->next == vmem.vaddr(segno, buddy));
prev->next = block->next;
} else {
// head of freelist.
assert(vmem.freelist[level] == vmem.vaddr(segno, buddy));
vmem.freelist[level] = block->next;
}
if (next) {
assert(next->prev == vmem.vaddr(segno, buddy));
next->prev = block->prev;
}
// coalesce block with buddy
level++;
if (buddy < addr)
addr = buddy;
}
// Add coalesced block to free list
Block *block = seg.block_ptr(addr);
block->prev = VADDR_NULL;
block->next = vmem.freelist[level];
block->mark_as_free(level);
vaddr_t blockaddr = vmem.vaddr(segno, addr);
if (block->next != VADDR_NULL)
vmem.block_ptr(block->next)->prev = blockaddr;
vmem.freelist[level] = blockaddr;
unlock_allocator();
}
next
ListNode * next
Definition janet.h:31
vspace::internals::find_buddy
static segaddr_t find_buddy(segaddr_t addr, int level)
Definition vspace.h:1690
vspace::internals::segaddr_t
size_t segaddr_t
Definition vspace.h:1412
vspace::internals::Block::level
int level()
Definition vspace.h:1546
vspace::internals::VMem::vaddr
vaddr_t vaddr(size_t segno, segaddr_t addr)
Definition vspace.h:1602
vspace::internals::VSeg
Definition vspace.h:1566
vspace::internals::VSeg::is_free
bool is_free()
Definition vspace.h:1568
vspace::internals::VSeg::block_ptr
Block * block_ptr(segaddr_t addr)
Definition vspace.h:1571

## wait_signal()

ipc_signal_t vspace::internals::wait_signal | ( | bool | lock | ) |

Definition at line 1075 of file vspace.cc.

{
return check_signal(true, lock);
}
vspace::internals::check_signal
ipc_signal_t check_signal(bool resume, bool lock)
Definition vspace.cc:990

## Variable Documentation

## config

size_t vspace::internals::config = { METABLOCK_SIZE, MAX_PROCESS, SEGMENT_SIZE, MAX_SEGMENTS }

Definition at line 618 of file vspace.cc.

{ METABLOCK_SIZE, MAX_PROCESS, SEGMENT_SIZE, MAX_SEGMENTS };
vspace::internals::SEGMENT_SIZE
static const size_t SEGMENT_SIZE
Definition vspace.h:1424
vspace::internals::MAX_PROCESS
static const int MAX_PROCESS
Definition vspace.h:1419

## LOG2_MAX_SEGMENTS

const int vspace::internals::LOG2_MAX_SEGMENTS = 10

static

Definition at line 1422 of file vspace.h.

## LOG2_SEGMENT_SIZE

const int vspace::internals::LOG2_SEGMENT_SIZE = 28

static

Definition at line 1421 of file vspace.h.

## MAX_PROCESS

const int vspace::internals::MAX_PROCESS = 64

static

Definition at line 1419 of file vspace.h.

## MAX_SEGMENTS

const size_t vspace::internals::MAX_SEGMENTS = 1 << LOG2_MAX_SEGMENTS

static

Definition at line 1423 of file vspace.h.

## METABLOCK_SIZE

const size_t vspace::internals::METABLOCK_SIZE = 128 * 1024

static

Definition at line 1420 of file vspace.h.

## SEGADDR_NULL

const segaddr_t vspace::internals::SEGADDR_NULL = ~(segaddr_t) 0

Definition at line 1416 of file vspace.h.

## SEGMENT_MASK

const size_t vspace::internals::SEGMENT_MASK = (SEGMENT_SIZE - 1)

static

Definition at line 1425 of file vspace.h.

## SEGMENT_SIZE

const size_t vspace::internals::SEGMENT_SIZE = 1 << LOG2_SEGMENT_SIZE

static

Definition at line 1424 of file vspace.h.

## VADDR_NULL

const vaddr_t vspace::internals::VADDR_NULL = ~(segaddr_t) 0

Definition at line 1417 of file vspace.h.

## vmem

VMem& vspace::internals::vmem = VMem::vmem_global

static

Definition at line 1635 of file vspace.h.