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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
#define _L4_TEST_MAIN
#include "t-environment.h"
#include <hurd/types.h>
#include <hurd/stddef.h>
#include "memory.h"
#include "cap.h"
#include "object.h"
#include "activity.h"
#include "as.h"
struct activity *root_activity;
/* Current working folio. */
static struct folio *folio;
static int object;
static struct as_insert_rt
allocate_object (enum cap_type type, addr_t addr)
{
if (! folio || object == FOLIO_OBJECTS)
{
folio = folio_alloc (root_activity, FOLIO_POLICY_DEFAULT);
object = 0;
}
struct as_insert_rt rt;
rt.cap = folio_object_alloc (root_activity, folio, object ++,
type, OBJECT_POLICY_DEFAULT, 0);
/* We don't need to set RT.STORAGE as as_insert doesn't require it
for the internal interface implementations. */
rt.storage = ADDR (0, 0);
return rt;
}
extern char _start;
extern char _end;
void
test (void)
{
if (! memory_reserve ((l4_word_t) &_start, (l4_word_t) &_end,
memory_reservation_self))
panic ("Failed to reserve memory for self.");
memory_grab ();
object_init ();
/* Create the root activity. */
folio = folio_alloc (NULL, FOLIO_POLICY_DEFAULT);
if (! folio)
panic ("Failed to allocate storage for the initial task!");
struct cap c = allocate_object (cap_activity_control, ADDR_VOID).cap;
root_activity = (struct activity *) cap_to_object (root_activity, &c);
folio_parent (root_activity, folio);
#define N 20
void try (struct activity *activity, struct folio *folio, int depth)
{
int i;
int obj = 0;
struct
{
struct activity *child;
struct folio *folio;
struct object *page;
} a[N];
for (i = 0; i < N; i ++)
{
struct object *object;
/* Allocate a new activity. */
struct cap cap;
cap = folio_object_alloc (activity, folio, obj ++,
cap_activity_control,
OBJECT_POLICY_DEFAULT, 0);
a[i].child = (struct activity *) cap_to_object (activity, &cap);
/* Allocate a folio against the activity and use it. */
a[i].folio = folio_alloc (a[i].child, FOLIO_POLICY_DEFAULT);
assert (a[i].folio);
cap = folio_object_alloc (a[i].child, a[i].folio, 0,
cap_page, OBJECT_POLICY_DEFAULT, 0);
a[i].page = cap_to_object (activity, &cap);
assert (object_type (a[i].page) == cap_page);
}
if (depth > 0)
/* Create another hierarchy depth. */
for (i = 0; i < 2; i ++)
try (a[i].child, a[i].folio, depth - 1);
/* We destroy the first N / 2 activities. The caller will
destroy the rest. */
for (i = 0; i < N / 2; i ++)
{
struct cap cap = object_to_cap (a[i].page);
struct object *o = cap_to_object (activity, &cap);
assert (o == a[i].page);
/* Destroy the activity. */
folio_free (activity, a[i].folio);
o = cap_to_object (activity, &cap);
assert (! o);
}
}
int i;
for (i = 0; i < 10; i ++)
{
struct folio *f = folio_alloc (root_activity, FOLIO_POLICY_DEFAULT);
assert (f);
try (root_activity, f, 4);
folio_free (root_activity, f);
}
}
|