summaryrefslogtreecommitdiff
path: root/viengoos/t-activity.c
blob: 2351f3be73e1399e2930f75b94fe89ed26969a37 (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
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);
    }
}