/* begincopyright Copyright (c) 1988 Xerox Corporation. All rights reserved. Use and copying of this software and preparation of derivative works based upon this software are permitted. Any distribution of this software or derivative works must comply with all applicable United States export control laws. This software is made available AS IS, and Xerox Corporation makes no warranty about the software, its performance or its conformity to any specification. Any person obtaining a copy of this software is requested to send their name and post office or electronic mail address to: PCR Coordinator Xerox PARC 3333 Coyote Hill Rd. Palo Alto, CA 94304 endcopyright */ /* * ThreadsSharedMem.h * * Demers, December 5, 1990 8:24:18 am PST */ #ifndef ←XR←THREADS←SHARED←MEM← #define ←XR←THREADS←SHARED←MEM← 1 #ifndef ←XR←BASIC←TYPES← #include "BasicTypes.h" #endif /* * VM size parameters and operations */ #define XR←ROUND←UP 1 #define XR←ROUND←DOWN (-1) #define XR←DONT←ROUND 0 extern XR←Pointer XR←ComputeAddress (/* XR←Pointer addr, unsigned bytes, int round */); /* Return (addr + bytes), rounded to page boundary as specified by `round'. */ extern unsigned XR←RoundToPage(/* unsigned sizeVal, int round */); /* Return sizeVal, page-rounded as specified by 'round'. */ #define XR←PAGE←ALIGNED(x) \ (((unsigned)(x)) == XR←RoundToPage(((unsigned)(x)), XR←ROUND←DOWN)) extern int XR←GetPageSize(); /* Return page size of this machine. Equivalent to (int) XR←ComputeAddress( (XR←Pointer)0, 1, XR←ROUND←UP ). */ extern int XR←GetWorstCasePageSize(); /* Return largest page size used on any machine of this architecture. */ extern XR←Pointer XR←VMReserve (/* unsigned bytes */); /* Reserve at least bytes of page-aligned virtual address space. Call during initialization (before FORK, after InitSharedSysMem) or from a thread. */ /* * Package initialization */ extern char * /* NIL or err msg */ XR←SetShmType(/* char * shmType */); extern char * XR←GetShmType(); extern char * /* NIL or err msg */ XR←SetShmArg(/* char * shmArg */); extern char * XR←GetShmArg(); extern char * /* NIL or err msg */ XR←InitSharedMem(); /* The PCR command line argument is shmtype type [arg] XR←SetShmType/XR←SetShmArg set these. They should be called at most once, in that order, before anything else in this interface. Finally, XR←InitSharedMem should be called. This happens automatically at the beginning of the PCR world. */ extern void XR←CleanUpSharedMem(); /* Free resources allocated by the shared memory implementation. Called automatically at end of PCR world. */ /* * Shared data + bss */ extern char * /* NIL or err msg */ XR←ShareMemInitial (/* XR←pointer p */); /* Arrange for all data and bss addresses above p to be shared among all the VPs and IOPs. The value of p must be page-aligned. Call only once, and only during initialization, before FORK. */ /* * System memory */ extern char * /* NIL or err msg */ XR←InitSharedSysMem(/* unsigned nBytes */); /* Initialize "system" memory with at least nBytes available. Call only once, during initialization, before FORK, before any call to XR←AllocSharedSysMem. */ extern XR←Pointer XR←AllocSharedSysMem(/* unsigned nBytes */); /* Allocate and clear a most-restrictively-aligned (e.g. doubleword on SPARC) block of shared memory. It can never be freed. Return NIL if out of memory. Call any time (initialization or thread) after calling InitSharedSysMem. */ /* * Stacks */ extern char * /* NIL or err msg */ XR←InitSharedStackMem(/* unsigned maxStacks, unsigned totalBytes */); /* Initialize for "stack" memory allocation for maxStacks thread stacks whose size totals to at most totalBytes. Call once during initialization (before FORK). */ extern XR←Pointer XR←AllocSharedStackMem(/* int index, unsigned nBytes */); /* Allocate and map a stack memory. A page of protected memory is automatically provided below each stack, so all the memory that's returned is accessible. Call during initialization (before FORK), after InitSharedStackMem. */ extern int /* bytesRemaining or -errno */ XR←FlushSharedStackMem(/* int index, XR←Pointer pLow, pHigh, int minBytesToFlush, int *pBytesFlushed */); /* Assume pLow .. pHigh is cold end of index'th stack (which must be a different thread from the caller). The index is the value passed to AllocSharedStackMem. Discard the stack (hotter than) p: * all protections remain unchanged * stack contents hotter than p may change * backing store resources may be released If the number of bytes of backing store that can be released is less than minBytesToFlush, don't bother. Return the number of bytes that remain allocated to the stack (or -errno on failure), and if pBytesFlushed is not NIL store the number of bytes flushed there. Call from a (daemon) thread. The victim thread should not be running at the time. This is not guaranteed to do anything -- it's just resource reclaiming advice. */ /* * Heap Segments */ typedef struct XR←SegRep { XR←Pointer seg←addr; /* virtual address where segment is mapped */ unsigned seg←bytes; /* size of segment */ } * XR←Seg; extern void XR←InitSeg2(/* XR←Seg seg, XR←Pointer vaddr, unsigned bytes, */); /* Initialize segment descriptor to represent 0 bytes at `vaddr'. Do not map the segment. */ extern void XR←ExtendSeg (/* XR←Seg seg, unsigned bytes */); /* Extend size of shared memory segment described in `seg' by `bytes'. Do not map the segment. */ extern void XR←InitSeg (/* XR←Seg seg, XR←Pointer vaddr */); extern XR←Pointer XR←InitSharedHeapMem(/* unsigned nBytes */); /* Initialize heap, with given max size. This doesn't map the memory, just reserves it. Call once during initialization (before FORK). Return address of reserved vm, or NIL if failed. */ extern int /* -errno */ XR←MapSharedHeapSeg(/* XR←Seg seg */); /* Arrange for page-aligned region of heap memory (described by seg) to be mapped and shared among all VPs and IOPs. The segment should not already be mapped. Call during initialization (before FORK) or from a thread. Return 0 on success. */ extern bool XR←ApplyToSysMem(/* bool (*proc)(void *start, void *limit, void *clientData), void *clientData */); /* Apply proc to every area of shared system memory that is "interesting" -- i.e. might be a root for the garbage collector. This includes the thread descriptors and thread stacks. It does not include PCR data or bss. Won't crash if the world is running, but it's only meaningful if the world is stopped. The enumeration terminates if proc ever returns FALSE. Result is last value returned by proc. */ #endif ←XR←THREADS←SHARED←MEM←