My Project
Data Structures | Typedefs | Enumerations | Functions | Variables
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 ProcessInfoprocess_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 ()
 
Blockblock_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 VMemvmem = 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

Definition at line 1481 of file vspace.h.

◆ segaddr_t

Definition at line 1412 of file vspace.h.

◆ vaddr_t

Definition at line 1414 of file vspace.h.

Enumeration Type Documentation

◆ SignalState

Enumerator
Waiting 
Pending 
Accepted 

Definition at line 1493 of file vspace.h.

1493  {
1494  Waiting = 0,
1495  Pending = 1,
1496  Accepted = 2,
1497 };

Function Documentation

◆ accept_signals()

void vspace::internals::accept_signals ( )

Definition at line 981 of file vspace.cc.

981  {
985 }
static void unlock_process(int processno)
Definition: vspace.cc:911
static void lock_process(int processno)
Definition: vspace.cc:905
static ProcessInfo & process_info(int processno)
Definition: vspace.cc:917
static VMem & vmem
Definition: vspace.h:1635

◆ allocated_ptr_to_vaddr()

static vaddr_t vspace::internals::allocated_ptr_to_vaddr ( void *  ptr)
inlinestatic

Definition at line 1697 of file vspace.h.

1697  {
1698  char *addr = (char *) ptr - sizeof(Block);
1699  vaddr_t info = ((Block *) addr)->prev;
1700  int seg = info & (MAX_SEGMENTS - 1);
1701  unsigned char *segstart = vmem.segments[seg].base;
1702  size_t offset = (unsigned char *) ptr - segstart;
1703  return (seg << LOG2_SEGMENT_SIZE) | offset;
1704 }
const ExtensionInfo & info
< [in] sqrfree poly
STATIC_VAR int offset
Definition: janet.cc:29
size_t vaddr_t
Definition: vspace.h:1414
static const size_t MAX_SEGMENTS
Definition: vspace.h:1423
static const int LOG2_SEGMENT_SIZE
Definition: vspace.h:1421
VSeg segments[MAX_SEGMENTS]
Definition: vspace.h:1594
unsigned char * base
Definition: vspace.h:1567

◆ block_ptr()

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

Definition at line 1637 of file vspace.h.

1637  {
1638  return vmem.block_ptr(vaddr);
1639 }
Block * block_ptr(vaddr_t vaddr)
Definition: vspace.h:1610

◆ check_signal()

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

Definition at line 944 of file vspace.cc.

944  {
946  if (lock)
949  switch (sigstate) {
950  case Waiting:
951  case Pending: {
953  char buf[1];
954  if (lock && sigstate == Waiting) {
956  while (read(fd, buf, 1) != 1) {
957  }
959  } else {
960  while (read(fd, buf, 1) != 1) {
961  }
962  }
965  = resume ? Waiting : Accepted;
966  if (lock)
968  break;
969  }
970  case Accepted:
972  if (resume)
974  if (lock)
976  break;
977  }
978  return result;
979 }
return result
Definition: facAbsBiFact.cc:75
int status read
Definition: si_signals.h:59
int status int void * buf
Definition: si_signals.h:59
int status int fd
Definition: si_signals.h:59
ProcessChannel channels[MAX_PROCESS]
Definition: vspace.h:1595

◆ drop_pending_signals()

void vspace::internals::drop_pending_signals ( )

◆ find_buddy()

static segaddr_t vspace::internals::find_buddy ( segaddr_t  addr,
int  level 
)
inlinestatic

Definition at line 1690 of file vspace.h.

1690  {
1691  return addr ^ (1 << level);
1692 }
int level(const CanonicalForm &f)

◆ find_level()

static int vspace::internals::find_level ( size_t  size)
inlinestatic

Definition at line 1681 of file vspace.h.

1681  {
1682  int level = 0;
1683  while ((1 << (level + 8)) <= size)
1684  level += 8;
1685  while ((1 << level) < size)
1686  level++;
1687  return level;
1688 }
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 858 of file vspace.cc.

859  {
860  lock_info.l_start = offset;
861  lock_info.l_len = len;
862  lock_info.l_pid = 0;
863  lock_info.l_type = lock ? F_WRLCK : F_UNLCK;
864  lock_info.l_whence = SEEK_SET;
865 }
#define SEEK_SET
Definition: mod2.h:115

◆ init_metapage()

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

Definition at line 887 of file vspace.cc.

887  {
888  if (create)
889  ftruncate(vmem.fd, METABLOCK_SIZE);
890  vmem.metapage = (MetaPage *) mmap(
891  NULL, METABLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, vmem.fd, 0);
892  if (create) {
893  std::memcpy(vmem.metapage->config_header, config, sizeof(config));
894  for (int i = 0; i <= LOG2_SEGMENT_SIZE; i++) {
896  }
898  vmem.metapage->allocator_lock = FastLock(metapageaddr(allocator_lock));
899  } else {
900  assert(std::memcmp(vmem.metapage->config_header, config,
901  sizeof(config)) != 0);
902  }
903 }
int i
Definition: cfEzgcd.cc:132
NodeM * create()
Definition: janet.cc:757
const vaddr_t VADDR_NULL
Definition: vspace.h:1417
vaddr_t freelist[LOG2_SEGMENT_SIZE+1]
Definition: vspace.h:1511
static const size_t METABLOCK_SIZE
Definition: vspace.h:1420
size_t config[4]
Definition: vspace.cc:573
internals::Mutex FastLock
Definition: vspace.h:2340
#define NULL
Definition: omList.c:12
MetaPage * metapage
Definition: vspace.h:1589
#define assert(A)
Definition: svd_si.h:3
#define metapageaddr(field)
Definition: vspace.cc:580

◆ lock_allocator()

static void vspace::internals::lock_allocator ( )
static

Definition at line 720 of file vspace.cc.

720  {
722 }

◆ lock_file()

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

Definition at line 867 of file vspace.cc.

867  {
868  struct flock lock_info;
869  init_flock_struct(lock_info, offset, len, true);
870  fcntl(fd, F_SETLKW, &lock_info);
871 }
void init_flock_struct(struct flock &lock_info, size_t offset, size_t len, bool lock)
Definition: vspace.cc:858

◆ lock_metapage()

void vspace::internals::lock_metapage ( )

Definition at line 879 of file vspace.cc.

879  {
880  lock_file(vmem.fd, 0);
881 }
void lock_file(int fd, size_t offset, size_t len)
Definition: vspace.cc:867

◆ lock_process()

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

Definition at line 905 of file vspace.cc.

905  {
906  lock_file(vmem.fd,
908  + sizeof(ProcessInfo) * vmem.current_process);
909 }

◆ print_freelists()

static void vspace::internals::print_freelists ( )
static

Definition at line 728 of file vspace.cc.

728  {
729  for (int i = 0; i <= LOG2_SEGMENT_SIZE; i++) {
730  vaddr_t vaddr = vmem.freelist[i];
731  if (vaddr != VADDR_NULL) {
732  std::printf("%2d: %ld", i, (long)vaddr);
733  vaddr_t prev = block_ptr(vaddr)->prev;
734  if (prev != VADDR_NULL) {
735  std::printf("(%ld)", (long)prev);
736  }
737  assert(block_ptr(vaddr)->prev == VADDR_NULL);
738  for (;;) {
739  vaddr_t last_vaddr = vaddr;
740  Block *block = block_ptr(vaddr);
741  vaddr = block->next;
742  if (vaddr == VADDR_NULL)
743  break;
744  std::printf(" -> %ld", (long)vaddr);
745  vaddr_t prev = block_ptr(vaddr)->prev;
746  if (prev != last_vaddr) {
747  std::printf("(%ld)", (long)prev);
748  }
749  }
750  std::printf("\n");
751  }
752  }
753  std::fflush(stdout);
754 }
Block * block_ptr(vaddr_t vaddr)
Definition: vspace.h:1637
#define block
Definition: scanner.cc:646

◆ process_info()

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

Definition at line 917 of file vspace.cc.

917  {
918  return vmem.metapage->process_info[processno];
919 }
ProcessInfo process_info[MAX_PROCESS]
Definition: vspace.h:1513

◆ send_signal()

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

Definition at line 921 of file vspace.cc.

921  {
922  if (lock)
923  lock_process(processno);
924  if (process_info(processno).sigstate != Waiting) {
925  unlock_process(processno);
926  return false;
927  }
928  if (processno == vmem.current_process) {
929  process_info(processno).sigstate = Accepted;
930  process_info(processno).signal = sig;
931  } else {
932  process_info(processno).sigstate = Pending;
933  process_info(processno).signal = sig;
934  int fd = vmem.channels[processno].fd_write;
935  char buf[1] = { 0 };
936  while (write(fd, buf, 1) != 1) {
937  }
938  }
939  if (lock)
940  unlock_process(processno);
941  return true;
942 }
int status int void size_t count write
Definition: si_signals.h:67

◆ unlock_allocator()

static void vspace::internals::unlock_allocator ( )
static

Definition at line 724 of file vspace.cc.

724  {
726 }

◆ unlock_file()

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

Definition at line 873 of file vspace.cc.

873  {
874  struct flock lock_info;
875  init_flock_struct(lock_info, offset, len, false);
876  fcntl(fd, F_SETLKW, &lock_info);
877 }

◆ unlock_metapage()

void vspace::internals::unlock_metapage ( )

Definition at line 883 of file vspace.cc.

883  {
884  unlock_file(vmem.fd, 0);
885 }
void unlock_file(int fd, size_t offset, size_t len)
Definition: vspace.cc:873

◆ unlock_process()

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

Definition at line 911 of file vspace.cc.

911  {
914  + sizeof(ProcessInfo) * vmem.current_process);
915 }

◆ vmem_alloc()

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

Definition at line 808 of file vspace.cc.

808  {
809  lock_allocator();
810  #if defined(__GNUC__) && (__GNUC__>11)
811  size_t alloc_size = size + (sizeof(vaddr_t)*2);
812  #else
813  size_t alloc_size = size + offsetof(Block, data);
814  #endif
815  int level = find_level(alloc_size);
816  int flevel = level;
817  while (flevel < LOG2_SEGMENT_SIZE && vmem.freelist[flevel] == VADDR_NULL)
818  flevel++;
819  if (vmem.freelist[flevel] == VADDR_NULL) {
820  vmem.add_segment();
821  }
823  while (flevel > level) {
824  // get and split a block
825  vaddr_t blockaddr = vmem.freelist[flevel];
826  assert((blockaddr & ((1 << flevel) - 1)) == 0);
827  Block *block = vmem.block_ptr(blockaddr);
828  vmem.freelist[flevel] = block->next;
829  if (vmem.freelist[flevel] != VADDR_NULL)
831  vaddr_t blockaddr2 = blockaddr + (1 << (flevel - 1));
832  Block *block2 = vmem.block_ptr(blockaddr2);
833  flevel--;
834  block2->next = vmem.freelist[flevel];
835  block2->prev = blockaddr;
836  block->next = blockaddr2;
837  block->prev = VADDR_NULL;
838  // block->prev == VADDR_NULL already.
839  vmem.freelist[flevel] = blockaddr;
840  }
842  Block *block = vmem.block_ptr(vmem.freelist[level]);
843  vaddr_t vaddr = vmem.freelist[level];
844  #if defined(__GNUC__) && (__GNUC__>11)
845  vaddr_t result = vaddr + (sizeof(vaddr_t)*2);
846  #else
847  vaddr_t result = vaddr + offsetof(Block, data);
848  #endif
849  vmem.freelist[level] = block->next;
850  if (block->next != VADDR_NULL)
851  vmem.block_ptr(block->next)->prev = VADDR_NULL;
852  block->mark_as_allocated(vaddr, level);
854  memset(block->data, 0, size);
855  return result;
856 }
static void lock_allocator()
Definition: vspace.cc:720
static int find_level(size_t size)
Definition: vspace.h:1681
static void unlock_allocator()
Definition: vspace.cc:724
void ensure_is_mapped(vaddr_t vaddr)
Definition: vspace.h:1615

◆ vmem_free()

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

Definition at line 756 of file vspace.cc.

756  {
757  lock_allocator();
758  #if defined(__GNUC__) && (__GNUC__>11)
759  vaddr -= (sizeof(vaddr_t)*2);
760  #else
761  vaddr -= offsetof(Block, data);
762  #endif
763  vmem.ensure_is_mapped(vaddr);
764  size_t segno = vmem.segment_no(vaddr);
765  VSeg seg = vmem.segment(vaddr);
766  segaddr_t addr = vmem.segaddr(vaddr);
767  int level = seg.block_ptr(addr)->level();
768  assert(!seg.is_free(addr));
769  while (level < LOG2_SEGMENT_SIZE) {
770  segaddr_t buddy = find_buddy(addr, level);
771  Block *block = seg.block_ptr(buddy);
772  // is buddy free and at the same level?
773  if (!block->is_free() || block->level() != level)
774  break;
775  // remove buddy from freelist.
776  Block *prev = vmem.block_ptr(block->prev);
777  Block *next = vmem.block_ptr(block->next);
778  block->data[0] = level;
779  if (prev) {
780  assert(prev->next == vmem.vaddr(segno, buddy));
781  prev->next = block->next;
782  } else {
783  // head of freelist.
784  assert(vmem.freelist[level] == vmem.vaddr(segno, buddy));
785  vmem.freelist[level] = block->next;
786  }
787  if (next) {
788  assert(next->prev == vmem.vaddr(segno, buddy));
789  next->prev = block->prev;
790  }
791  // coalesce block with buddy
792  level++;
793  if (buddy < addr)
794  addr = buddy;
795  }
796  // Add coalesced block to free list
797  Block *block = seg.block_ptr(addr);
798  block->prev = VADDR_NULL;
799  block->next = vmem.freelist[level];
800  block->mark_as_free(level);
801  vaddr_t blockaddr = vmem.vaddr(segno, addr);
802  if (block->next != VADDR_NULL)
803  vmem.block_ptr(block->next)->prev = blockaddr;
804  vmem.freelist[level] = blockaddr;
806 }
ListNode * next
Definition: janet.h:31
static segaddr_t find_buddy(segaddr_t addr, int level)
Definition: vspace.h:1690
size_t segaddr_t
Definition: vspace.h:1412
size_t segment_no(vaddr_t vaddr)
Definition: vspace.h:1599
VSeg segment(vaddr_t vaddr)
Definition: vspace.h:1596
vaddr_t vaddr(size_t segno, segaddr_t addr)
Definition: vspace.h:1602
segaddr_t segaddr(vaddr_t vaddr)
Definition: vspace.h:1605

◆ wait_signal()

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

Definition at line 987 of file vspace.cc.

987  {
988  return check_signal(true, lock);
989 }
ipc_signal_t check_signal(bool resume, bool lock)
Definition: vspace.cc:944

Variable Documentation

◆ config

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

Definition at line 572 of file vspace.cc.

◆ 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.