summaryrefslogtreecommitdiff
path: root/libhurd-mm/storage.h
blob: c3ea15140dc34f41fba47ffaa5a4f86e7c378563 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/* storage.h - Storage allocation functions.
   Copyright (C) 2007, 2008 Free Software Foundation, Inc.
   Written by Neal H. Walfield <neal@gnu.org>.

   This file is part of the GNU Hurd.

   The GNU Hurd is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU Hurd is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#ifndef _HURD_STORAGE_H
#define _HURD_STORAGE_H

#include <viengoos/addr.h>
#include <viengoos/cap.h>

enum storage_expectancy
  {
    /* Storage with an unknown life expectancy.  */
    STORAGE_UNKNOWN = 0,
    /* Storage that is likely to be deallocated quickly (seconds to a
       couple of minutes).  */
    STORAGE_EPHEMERAL,
    /* Storage that is likely to be deallocated at some time, but
       program will continue running much longer.  */
    STORAGE_MEDIUM_LIVED,
    /* Storage with an expected long-life (storage will most likely
       not be deallocated).  */
    STORAGE_LONG_LIVED,
  };

struct storage
{
  struct vg_cap *cap;
  vg_addr_t addr;
};

/* Allocate an object of type TYPE.  The object has a life expectancy
   of EXPECTANCY.  If ADDR is not VG_ADDR_VOID, a capability to the
   storage will be saved at ADDR (and the shadow object updated
   appropriately).  On success, the shadow capability slot for the
   storage is returned (useful for setting up a shadow object) and the
   address of the storage object.  Otherwise, NULL and VG_ADDR_VOID,
   respectively, are returned.  ACTIVITY is the activity to use to
   account the storage.

   NB: This function does not allocate a shadow object for the
   allocated object; it does update the relevant shadow objects so
   that the address of the storage and ADDR are reachable.  If the
   caller wants to use the allocated object for address translation,
   the caller must allocate the shadow object.  If not, functions
   including the cap_lookup family will fail.  */
extern struct storage storage_alloc (vg_addr_t activity,
				     enum vg_cap_type type,
				     enum storage_expectancy expectancy,
				     struct vg_object_policy policy,
				     vg_addr_t addr);
#define storage_alloc(__sa_activity, __sa_type, __sa_expectancy,	\
		      __sa_policy, __sa_addr)				\
  ({									\
    struct storage __sa_storage;					\
    __sa_storage = storage_alloc (__sa_activity, __sa_type,		\
				  __sa_expectancy, __sa_policy,		\
				  __sa_addr);				\
    debug (5, "storage_alloc (%s, " VG_ADDR_FMT ") -> " VG_ADDR_FMT,		\
	   vg_cap_type_string (__sa_type), VG_ADDR_PRINTF (__sa_addr),	\
	   VG_ADDR_PRINTF (__sa_storage.addr));				\
    __sa_storage;							\
  })


/* Frees the storage at STORAGE.  STORAGE must be the address returned
   by storage_alloc (NOT the address provided to storage_alloc).  If
   UNMAP_NOW is not true, revoking the storage may be delayed.  */
extern void storage_free_ (vg_addr_t storage, bool unmap_now);
#define storage_free(__sf_storage, __sf_unmap_now)			\
  ({									\
    debug (5, "storage_free (" VG_ADDR_FMT ")", VG_ADDR_PRINTF (__sf_storage)); \
    storage_free_ (__sf_storage, __sf_unmap_now);			\
  })

/* Initialize the storage sub-system.  */
extern void storage_init (void);

/* Used by as_init to initialize a folio's shadow object.  */
extern void storage_shadow_setup (struct vg_cap *cap, vg_addr_t folio);

/* Return whether there is sufficient reserve storage.  */
extern bool storage_have_reserve (void);

/* Check the amount of available storage, allocating more if required.
   This should be called by any function that takes the as_rwlock and
   allocates storage (even indirectly) after it has dropped the
   as_rwlock.  Pass false if you know that you do not hold the as_lock.
   True otherwise.  */
extern void storage_check_reserve (bool i_may_have_as_lock);

#endif /* _HURD_STORAGE_H  */