


/*
 * Copyright (c) 1990, Geometry Supercomputer Project
 *                     University of Minnesota 
 *                     1200 Washington Ave. S
 *                     Minneapolis, MN  55415
 *
 * email address: software@geom.umn.edu
 *
 * This software is copyrighted as noted above.  It may be freely copied,
 * modified, and redistributed, provided that the copyright notice is
 * preserved on all copies.
 *
 * There is no warranty or other guarantee of fitness for this software,
 * it is provided solely "as is".  Bug reports or fixes may be sent
 * to the authors, who may or may not act on them as they desire.
 *
 * You may not include this software in a program or other software product
 * without supplying the source, or without informing the end-user that the
 * source is available for no extra charge.
 *
 * If you modify this software, you should include a notice giving the
 * name of the person performing the modification, the date of modification,
 * and the reason for such modification.
 */



#ifndef _GEOM_SM_
#define _GEOM_SM_
/*
 * Declarations for shared-memory geometry objects.
 * $Header: /usr2/gcg/grap/src/lib/oogl/libgeom/RCS/geom_sm.h,v 1.2 90/05/07 14:19:44 meuer Exp $
 *
 * $Log:	geom_sm.h,v $
 * Revision 1.2  90/05/07  14:19:44  meuer
 * Automatic prepending of file /u/gcg/grap/document/copyright.
 * 
 * Revision 1.1  89/12/27  09:06:18  meuer
 * Initial revision
 * 
 * Revision 1.7  89/09/14  14:44:00  slevy
 * Add SM_RDONLY flag.
 * Change SysV shmem/sem GeomSMRegion fields: add sm_shmid[] and sm_semid[]'s.
 * 
 * Revision 1.6  89/09/12  23:04:26  slevy
 * Add s_lock field to GeomSMSym (sigh).
 * 
 * Revision 1.5  89/09/11  20:55:30  slevy
 * Add hook for using System V shmat() shared memory.
 * 
 * Revision 1.4  89/09/05  22:51:08  slevy
 * Add sm_ro (read only) flag.
 * 
 * Revision 1.3  89/08/09  12:28:10  slevy
 * Add GeomRefreshSM(sm) macro: call GeomRemapSM only if needed.
 * 
 * Revision 1.2  89/08/08  13:56:44  slevy
 * Tidy up; add IsInSM macro; add region sm_ctab field for class<=>name cache.
 * 
 * Revision 1.1  89/08/07  14:16:19  slevy
 * Initial revision
 * 
 */

  
typedef struct GeomSMSym  GeomSMSym;

typedef struct SharedGeom SharedGeom;


struct GeomSMSym {
	char	*s_here;	/* Addr of this GeomSMSym (owner's space) */
	long	s_size;		/* sizeof(Object) */
	char	*s_obj;		/* Object */
	int	s_version;	/* Might be good for something, else 0 */
	GeomSMSym *s_lnext;	/* Addr of left child symbol, else 0 */
	GeomSMSym *s_rnext;	/* Addr of right child */
	long	s_lock;		/* what to lock with; encoded; 0 if not set */
	unsigned char        s_namelen;	/* Length of name */
	char	s_name[1];	/* NUL-terminated symbol name, var. size */
};

typedef struct GeomSMRegion {
	char *sm_base;		/* Base address where shared mem is mapped */
	long  sm_mapped;	/* Amount of shared memory currently mapped */
	int   sm_fd;		/* File descriptor of backing store file */
	short	sm_ro;		/* Flag: map read-only */
	short	sm_nseg;
#define MAXSMSEG 16
	long  sm_shift;	/* {addr in our space} - {addr in creator's space} */
	GeomSMSym *sm_mysym; /* Indicates process' interest in that SM */
	struct arena *sm_arena;	/* private per-SM malloc static data */
	struct classtab *sm_ctab; /* Known classes in this SM */
	int sm_shmid[MAXSMSEG];
	int sm_semid[MAXSMSEG];
} GeomSMRegion;



#define	IsInSM(addr, sm)   ((sm)->sm_base <= (char *)(addr) && \
			     (char *)(addr) < (sm)->sm_base + (sm)->sm_mapped)

#define	GeomRefreshSM(sm)  ((sm)->sm_mapped < ROOTSYM(sm)->s_size ? GeomRemapSM(sm) : (sm)->sm_mapped)

#define	ROOTSYM(sm)	((GeomSMSym *)(sm)->sm_base)

#define	GOffset(sym, type, ptr)  ((type *)(((char *)(ptr)) + \
				   (((char *)(sym)) - (sym)->s_here)))

extern GeomSMRegion *GeomCurSM;

#define	MAXSM		4	/* Max number of simultaneous shared mem's */

#define	SM_MAGIC  0x4AB3B8B9	/* s_version field for SM root symbol */

#define	SM_CREATE	0x1	/* create SM file if not there */
#define	SM_INIT		0x2	/* create regardless, destroy old data */
#define	SM_RDONLY	0x4	/* Map read-only */
#define	SM_ANYWHERE	0x8	/* OK to map at different addr than creator's */



GeomSMRegion *GeomOpenSM(char *fname, int flags);
char	*GeomGrowSM(GeomSMRegion *sm, int nbytes, int dontlock);
GeomSMRegion *GeomSMof(char *addr);
int	GeomUseMem(GeomSMRegion *sm);

GeomSMSym *GeomFindSym(GeomSMRegion *sm, char *name, GeomSMSym ***parentp);
GeomSMSym *GeomCreateSym(GeomSMRegion *sm, char *name, int room, int *didit);
int	 GeomDeleteSym(GeomSMRegion *sm, char *name);

int	 GeomLockSym(GeomSMRegion *sm, GeomSMSym *sym, int dontwait);
int	 GeomUnlockSym(GeomSMRegion *sm, GeomSMSym *sym);


/* GeomSMRegion *GeomOpenSM(fname, flags)
 *	Maps shared memory whose backing store is fname.
 *	Returns pointer to "GeomSMRegion", or
 *	or NULL on error (file not present, not r/w, corrupted, etc.)
 *	flags =  some combination of SM_CREATE, SM_INIT, SM_ANYWHERE
 */

/* char *GeomGrowSM(GeomSMRegion *sm, int nbytes, int dontlock)
 *	Extends the shared-memory region by "nbytes" bytes.
 *	Locks the shared memory's root symbol unless "dontlock" is nonzero
 *	(in which case the caller should already have locked it).
 *	Returns the address of the new chunk of shared memory, or NULL.
 */ 

/* GeomSMRegion *GeomSMof(addr)
 *	Discovers which shared-memory region a given address lies in.
 *	Returns the GeomSMRegion pointer, or
 *	NULL if the address is not in shared memory.
 */	

/* int GeomUseMem(sm) => 0 or -1
 *	Select that shared-memory region for Geom{Malloc,Free,Realloc}
 *	memory allocation.
 *	sm = NULL => revert to normal private memory allocator.
 *	Sets global GeomCurSM, sometimes function pointers.
 *	Returns 0 if OK, -1 if region invalid.
 */

/* GeomSMSym *GeomFindSym(GeomSMRegion *sm,
 *			      char *name,
 *			      GeomSMSym ***parentp)
 *	Search the shared memory for a symbol with the given name.
 *	Return the symbol address, or NULL.
 *	If "parentp" is not NULL, *parentp is set to the address of
 *	a "symbol *" field within some symbol in the table.
 *	This field points to the returned symbol if any,
 *	or would be set to point to that symbol if it were created.
 */

/* GeomSMSym *GeomCreateSym(GeomSMRegion *sm,
 *				char *name,
 *				int room,
 *				int *didit)
 *	Search the shared memory for a symbol with the given name,
 *	create it if it doesn't already exist.
 *	Returns the symbol address, or NULL if it couldn't be created.
 *	If didit is non-NULL, *didit is filled in with
 *		0 if the symbol already existed,
 *		1 if it didn't and was created,
 *		-1 if some error prevented its creation.
 *	If the symbol is created, "room" bytes of extra space are allotted
 *	and the new symbol's s_obj and s_size fields set to describe it.
 *	s_obj and s_size are untouched if the symbol already exists.
 */ 

/* int GeomDeleteSym(GeomSMRegion *sm, char *name)
 *	Delete the symbol with the given name from shared memory.
 *	Returns
 *		0 if the symbol didn't exist (wasn't deleted),
 *		1 if it was deleted,
 *		-1 if some error prevented its deletion.
 */

/* int GeomLockSym(GeomSMSym *sym, int dontwait)
 *	Lock the given shared memory symbol.
 *	Uses lockf() on the appropriate region of the mmap'ed file.
 *	If dontwait is nonzero, returns an error if already locked;
 *	otherwise blocks until the lock can be applied.
 *	Returns 0 on success, -1 on error.
 */

/* int GeomUnlockSym()
 *	Unlock the given shared memory symbol
 */

	/************************************/
	/* Geometry shared memory interface */

extern GeomSMRegion *GeomCurSM;	/* Public read-only, used e.g. by mallocators */

extern char *GeomSMMalloc(int nb, GeomSMRegion *sm);
extern char *GeomSMRealloc(char *p, int nb, GeomSMRegion *sm);
extern void GeomSMFree(char *p, GeomSMRegion *sm);

#endif _GEOM_SM_
