1
0
Files
irix-657m-src/irix/kern/sys/anon.h
2022-09-29 17:59:04 +03:00

325 lines
12 KiB
C

/**************************************************************************
* *
* Copyright (C) 1986, Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
#ifndef __SYS_ANON_H__
#define __SYS_ANON_H__
#ifdef __cplusplus
extern "C" {
#endif
#ident "$Revision: 1.30 $"
#include <sys/types.h>
#include <sys/getpages.h>
/*
* Anonymous Memory Manager - External Interfaces
*
* The Anonymous Manager manages pages that have no copy in a file.
* This includes things like stack, bss, modified data, and modified
* MAP_PRIVATE mappings in general. The purpose of the Anonymous
* Manager is to remember which pages within a region are anonymous
* and where they are located (either in memory, on swap, or both). It
* also allows sharing of anonymous pages for copy-on-write purposes.
*
* All Anonymous Manager data structures are private and can only be
* accessed through the interfaces in this file. A handle is returned
* when anonymous memory is first initialized. This must be provided
* on all future calls. Most calls may sleep while waiting to allocate
* data structures.
*/
/*******************************************************************************
* handle = anon_new()
*
* Returns a handle to a new anonymous structure. Called when
* a new region is initialized.
*/
extern anon_hdl anon_new(void);
/*******************************************************************************
* anon_free(handle)
*
* Called to disassociate the region from its anonymous memory. The
* handle is no longer valid after this call.
*/
extern void anon_free(anon_hdl);
/*******************************************************************************
* child_hdl = anon_dup(&par_hdl)
*
* Called to dup the anonymous memory associated with par_hdl using
* copy-on-write. anon_dup may change the par_hdl.
*/
extern anon_hdl anon_dup(anon_hdl *);
/*******************************************************************************
* anon_hold(anon_hdl)
*
* Grab and hold a reference to the anonymous structure associated with the
* given handle. The caller must be holding a pfdat lock for a page
* associated with the anon handle. This call is used prior to calling
* routines like anon_recycle() and ensures that the handle won't be
* freed in the meantime.
*/
extern void anon_hold(anon_hdl);
/*******************************************************************************
* key = anon_lookup(handle, lpn, &swp_hdl)
*
* Checks to see if lpn is present in the anonymous memory associated
* with handle. If found, the cache key associated with the page is returned.
* A swap handle is also returned if a copy of the page can be found on swap.
* Returns 0 if page not found.
*/
extern void *anon_lookup(anon_hdl, pgno_t, sm_swaphandle_t *);
/*******************************************************************************
* pfd = anon_pfind(handle, lpn, &id, &swp_hdl)
*
* Checks to see if lpn is present in the anonymous memory associated
* with handle. If found, a cache key (id) is returned that can be used to
* identify the page in the page cache. If the page is in the page
* cache, a pointer to its pfdat is returned. A swap handle is also returned
* if a copy of the page can be found on swap. Returns 0 if page not found.
*/
extern struct pfdat *anon_pfind(anon_hdl, pgno_t, void **, sm_swaphandle_t *);
/*******************************************************************************
* key = anon_tag(handle)
*
* Return the cache key associated with the given anonymous handle. The
* result of anon_tag and anon_lookup is the same for any private pages
* the region has (those not being shared copy-on-write).
* (DO NOT RELY on the present implementation of this function!)
*/
#define anon_tag(handle) ((void *)(handle))
/*******************************************************************************
* anon_insert(handle, pfd, lpn, pdoneflag)
*
* Adds pfd as a new anonymous page to be managed by the Anonymous Manager.
* Lpn specifies the page's page number. This new page covers any existing
* copy-on-write page with the same lpn. Future calls to anon_lookup will
* return the data associated with the new page. The new page is assumed to
* have no swap associated with it. Any swap space associated with a covered
* page will eventually be released when all other references to it are gone.
*/
extern void anon_insert(anon_hdl, struct pfdat *, pgno_t, int);
/*******************************************************************************
* anon_modify(handle, pfd, sanon_region)
*
* Informs anonymous manager that the given page is being modified. If
* possible, the page is stolen for this process. This causes any swap
* information for the page to be discarded and the physical page to be made
* private to the given handle. If stealing isn't possible, the page state
* is left unchanged and the function return COPY_PAGE to inform the caller
* to copy it and anon_insert the new copy. The caller should pass true
* for the sanon_region flag if this is a shared anonymous region.
*/
typedef enum { PAGE_STOLEN, COPY_PAGE } anon_modify_ret_t;
extern anon_modify_ret_t anon_modify(anon_hdl, struct pfdat *, int);
/*******************************************************************************
* anon_swapin(handle, pfd, lpn)
*
* Informs anonymous manager that the given page has been/will be swapped
* in and should be inserted into the page cache. The swap handle associated
* with the page is left intact. It is up to the caller to set the P_DONE
* flag when the swap I/O is complete. Returns SUCCESS if page was inserted
* or returns DUPLICATE if the page is already present in the cache (meaning
* another process has already swapped in the the page).
*/
typedef enum { SUCCESS, DUPLICATE } anon_swapin_ret_t;
extern anon_swapin_ret_t anon_swapin(anon_hdl, struct pfdat *, pgno_t);
/*******************************************************************************
* anon_pagemigr(handle, old_pfd, new_pfd)
*
* Check whether the page represented by old_pfd is migratable and
* if so, copy its state to new_pfd, remove it from the pcache,
* and insert new_pfd.
*/
extern int anon_pagemigr(anon_hdl, struct pfdat *, struct pfdat *);
/*******************************************************************************
* anon_flip(old_pfd, new_pfd)
*
* Exchanges new_pfd for old_pfd in the page cache. All future lookup
* operations will find the new page. The old page is disassociated from
* the anonymous memory region and returned in the correct state for use
* as a kernel data page.
*/
extern void anon_flip(struct pfdat *, struct pfdat *);
/*******************************************************************************
* anon_setsize(handle, newsize)
*
* Set the size of an anonymous region to 'newsize' pages. Must be called
* when a region is shrunk so that stale anonymous pages can no longer be
* referenced by the reion. Does not need to be called when a region is
* grown. Does not allocate physical memory or swap on grow.
* Any swap space released as a result of a shrink will eventually be freed
* when the last reference goes away.
*/
extern void anon_setsize(anon_hdl, pgno_t);
/*******************************************************************************
* anon_getsizes(handle, start, len, anonpages, maxanon)
*
* Returns some size information about the anonymous region associated with
* the given handle. 'Start' and 'len' specify the range of pages being
* enquired about. 'Anonpages' and 'maxanon' are output parameters that, if
* non-NULL, give the total number of anonymous pages and the maximum anonymous
* page (as set by anon_insert) in the given range respectively. If there are
* no anonymous pages in the range, 'anonpages' is set to zero and 'maxanon'
* is set to -1. This function does not change the state of the anonymous
* memory in any way.
*/
extern void anon_getsizes(anon_hdl, pgno_t, pgno_t, pgno_t *, pgno_t *);
/*******************************************************************************
* anon_setswap_and_pagefree(pfd, swaphandle, do_pagedone)
*
* Set the swap handle on the given page and free the page. If the
* 'do_pagedone' flag is set, then a pagedone() call is made for this
* page.
*/
extern void anon_setswap_and_pagefree(struct pfdat *, sm_swaphandle_t, int);
/*******************************************************************************
* anon_pagefree_and_cache(pfd)
*
* Free an anonymous page. Continue caching the page even if the use
* count goes to zero. This is different than pagefreeanon() which tosses
* pages that have a use count of zero.
*/
extern void anon_pagefree_and_cache(struct pfdat *);
/*******************************************************************************
* anon_clrswap(key, lpn, swaphandle)
*
* Clearr the swap handle and free the swap space for the given lpn. Replace
* it with the new swaphandle if it is non-NULL. The 'key' must be the result
* of a anon_lookup request.
*/
extern void anon_clrswap(void *, pgno_t, sm_swaphandle_t);
/*******************************************************************************
* anon_remove(handle, lpn, npgs)
*
* Remove 'npgs' contiguous pages starting at lpn from the anonymous space
* associated with 'handle', and free any swap space backing those pages.
* The pages must have previously been inserted with anon_insert.
*/
extern void anon_remove(anon_hdl, pgno_t, pgno_t);
/*******************************************************************************
* anon_uncache(pfd)
*
* Remove the given page from the page cache. Any associated swap handle
* is left intact.
*/
extern void anon_uncache(struct pfdat *);
/*******************************************************************************
* anon_recycle(handle, pfd)
*
* Remove the given page from the page cache so that pagealloc can recycle
* it to a new use. The page must be in the recycle state: P_RECYCLE is
* set and the page has been removed from the free list. The caller must
* already have done an anon_hold on the anonymous handle. A swap handle
* must have been associated with the page at some previous point in time
* before the page can be recycled.
*/
extern void anon_recycle(anon_hdl, struct pfdat *);
/*******************************************************************************
* anon_isdegenerate(handle)
*
* Return true if the passed anon handle is the leaf of a degenerate tree.
* This is a tree where there is only one leaf which means there are no
* other processes sharing any of the pages with copy-on-write.
*/
extern int anon_isdegenerate(anon_hdl);
/*******************************************************************************
* anon_shake_tree(handle)
*
* Garbage collect any swap pages that are no longer needed. This happens
* when all processes that were sharing a page with copy-on-write have
* modified the page. This should only be called when swap space is running
* low. Swap space is normally reclaimed whenever a process exec's or exit's.
*/
extern void anon_shake_tree(anon_hdl);
/*******************************************************************************
* anon_pagebad(struct pfdat *)
*
* Remove the anon page from the page cache and mark it P_BAD.
*/
extern void anon_pagebad(struct pfdat *);
#ifdef __cplusplus
}
#endif
#endif /* __SYS_ANON_H__ */