/* start of part for mergemem.h */

/* replace this by __KERNEL__ */
#ifdef UWN__KERNEL__
#define IN const
#define OUT
#else
#define IN
#define OUT const
#endif

struct ioctl_getpageinfos
{
  IN  pid_t pid;                /* in */
  const void * IN start;              /* in */
  const void * IN end;                /* in */
  OUT MPAGEINFO * IN pageinfos; /* in *out */
  IN  size_t nel;               /* in */
  const void * OUT cont;              /* out */
  OUT size_t wel;               /* out, wel <= nel */
  OUT int errno;                /* out */
};

/* IOCTL_GETPAGEINFOS:

 Similar to m_getpageinfos.  start and end do not need to be page
 aligned.  In contrast to m_getpageinfos the number of actually
 written pages wel may be smaller than nel, even if further pages are
 available ( wel < nel && cont != NULL ).  Only cont indicates whether
 further pages are availabe.

 errno should by and large (!?!?) be the value visible beyond
 m_getpageinfos

*/

int IOCTL_GETPAGEINFOS( struct ioctl_getpageinfos * argsp);

typedef
enum { KHEXTERNAL, KHADDROTHALF, KHCONST }
KHASHMETHOD;

struct ioctl_hashpages
{
  IN  KHASHMETHOD khashmethod;  /* in */
  IN  pid_t pid;                /* in */
  OUT MPAGEINFO * IN pageinfos;  /* in *out */
  IN  size_t nel;               /* in */
  OUT size_t wel;               /* out, wel <= nel */
  OUT size_t succwel;           /* out, succwel <= wel */

  /* only needed for KHEXTERNAL: */

  OUT unsigned char * pbufferp; /* inout *out */
  IN  size_t size;              /* in */
  OUT size_t pagesize;          /* out  */
  OUT int errno;                /* out */
};

/* IOCTL_HASHPAGES

   Updates the first wel elements of pageinfos as m_hashpages.  From
   those, succwel pages were accessible for hashing.  In contrast to
   m_hashpages, wel may be smaller than nel, to avoid blocking the
   kernel too much or for other reasons.

   For all wel elements, the fields count and p_addr have been set to
   0/NULL, if the page was unavailable.

   If KHEXTERNAL is requested:

       pbufferp must have room for at least size bytes.  The kernel
       may choose either to use this space or update pbufferp to its
       own area.  After the call pbufferp points to an area filled
       with succwel pages of size pagesize.  pbufferp contains only
       those pages that have been successfully copied.  Those not
       successfully copied have pageinfos[i].count == 0.  If there are
       pages of different size, wel will be smaller than nel, a
       further call is required.
       
       If the value returned into pbufferp is not equal to the value
       provided by the caller, the kernel has set this pointer to its
       own area.  In this case, this value must not be altered by the
       caller.  It should be passed further to the next directly
       following IOCTL_HASHPAGES.  This allows the kernel to free this
       area and maybe assign a new area if applicable.  The caller
       must ensure that a kernel provided area is freed finally by an
       IOCTL_HASHPAGES using ioctl_hashpages.nel == 0.  Calls to
       IOCTL_HASHPAGES that return an error have freed their
       corresponding areas (if present) automatically.

       The fields hash in pageinfos are set to some value that must be
       xored with the return value of the user defined hash function.
       With field hash the kernel might avoid that pages with
       otherwise same hash value are considered candidates for
       merging.  On virtually addressed caches (eg. SPARC),
       incompatible virtual addresses are indicated to avoid useless
       requests with m_merge.  ?? On SMP systems, pages residing on
       different processors or memory subsystems *may* not be
       mergeable.  So field hash may be the id of the processor or
       memory subsystem.

*/


int IOCTL_HASHPAGES( struct ioctl_hashpages *argsp );


struct ioctl_mergepairs
{
  OUT MEQUALPAIR * IN pagepairs; /* in */
  IN  size_t nel;                /* in */
  OUT size_t wel;                /* out, wel <= nel */
  OUT size_t mergedpages;        /* out */
  OUT int errno;                 /* out */
};

int IOCTL_MERGEPAIRS( struct ioctl_mergepairs * argsp );

/* IOCTL_MERGEPAIRS:

   Similar to m_mergepairs.  But wel may be smaller than nel to avoid
   blocking the kernel too long.

*/


/* end of part for mergemem.h */
