/* 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←