summaryrefslogtreecommitdiff
path: root/viengoos/t-activity.c
blob: f3f5d834e1403aee8a46c6cc0e091f3683cf9f49 (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
#define _L4_TEST_MAIN
#include "t-environment.h"

#include <hurd/types.h>
#include <hurd/stddef.h>
#include <hurd/as.h>

#include "memory.h"
#include "cap.h"
#include "object.h"
#include "activity.h"

struct activity *root_activity;

/* Current working folio.  */
static struct vg_folio *folio;
static int object;

static struct as_allocate_pt_ret
allocate_object (enum vg_cap_type type, vg_addr_t addr)
{
  if (! folio || object == VG_FOLIO_OBJECTS)
    {
      folio = folio_alloc (root_activity, VG_FOLIO_POLICY_DEFAULT);
      object = 0;
    }

  struct as_allocate_pt_ret rt;
  rt.cap = folio_object_alloc (root_activity, folio, object ++,
			       type, VG_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 = VG_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, VG_FOLIO_POLICY_DEFAULT);
  if (! folio)
    panic ("Failed to allocate storage for the initial task!");

  struct vg_cap c = allocate_object (vg_cap_activity_control, VG_ADDR_VOID).cap;
  root_activity = (struct activity *) vg_cap_to_object (root_activity, &c);
    
  folio_parent (root_activity, folio);

#define N 20
  void try (struct activity *activity, struct vg_folio *folio, int depth)
  {
    int i;
    int obj = 0;

    struct
    {
      struct activity *child;
      struct vg_folio *folio;
      struct vg_object *page;
    } a[N];

    for (i = 0; i < N; i ++)
      {
	/* Allocate a new activity.  */
	struct vg_cap cap;
	cap = folio_object_alloc (activity, folio, obj ++,
				  vg_cap_activity_control,
				  VG_OBJECT_POLICY_DEFAULT, 0);
	a[i].child = (struct activity *) vg_cap_to_object (activity, &cap);

	/* Allocate a folio against the activity and use it.  */
	a[i].folio = folio_alloc (a[i].child, VG_FOLIO_POLICY_DEFAULT);
	assert (a[i].folio);

	cap = folio_object_alloc (a[i].child, a[i].folio, 0,
				  vg_cap_page, VG_OBJECT_POLICY_DEFAULT, 0);
	a[i].page = vg_cap_to_object (activity, &cap);
	assert (object_type (a[i].page) == vg_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 vg_cap cap = object_to_cap (a[i].page);
	struct vg_object *o = vg_cap_to_object (activity, &cap);
	assert (o == a[i].page);

	/* Destroy the activity.  */
	folio_free (activity, a[i].folio);

	o = vg_cap_to_object (activity, &cap);
	assert (! o);
      }
  }

  int i;
  for (i = 0; i < 10; i ++)
    {
      struct vg_folio *f = folio_alloc (root_activity, VG_FOLIO_POLICY_DEFAULT);
      assert (f);

      try (root_activity, f, 4);

      folio_free (root_activity, f);
    }
}