2 * \brief Domain internals for the process manager.
4 * Copyright (c) 2017, ETH Zurich.
7 * This file is distributed under the terms in the attached LICENSE file.
8 * If you do not find this file, copies can be found by writing to:
9 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
12 #include <barrelfish/barrelfish.h>
13 #include <collections/hash_table.h>
17 #define HASH_INDEX_BUCKETS 6151
18 static collections_hash_table* domain_table = NULL;
20 errval_t domain_new(struct capref domain_cap, struct domain_entry **ret_entry)
22 assert(ret_entry != NULL);
24 struct domain_entry *entry = (struct domain_entry*) malloc(
25 sizeof(struct domain_entry));
27 return LIB_ERR_MALLOC_FAIL;
30 entry->domain_cap = domain_cap;
31 entry->status = DOMAIN_STATUS_NIL;
32 entry->spawnds = NULL;
33 entry->waiters = NULL;
35 if (domain_table == NULL) {
36 collections_hash_create_with_buckets(&domain_table, HASH_INDEX_BUCKETS,
38 if (domain_table == NULL) {
39 return PROC_MGMT_ERR_CREATE_DOMAIN_TABLE;
44 errval_t err = domain_cap_hash(entry->domain_cap, &key);
45 if (err_is_fail(err)) {
49 collections_hash_insert(domain_table, key, entry);
56 errval_t domain_get_by_cap(struct capref domain_cap,
57 struct domain_entry **ret_entry)
59 assert(ret_entry != NULL);
62 errval_t err = domain_cap_hash(domain_cap, &key);
63 if (err_is_fail(err)) {
67 void *table_entry = collections_hash_find(domain_table, key);
68 if (table_entry == NULL) {
69 return PROC_MGMT_ERR_DOMAIN_TABLE_FIND;
71 *ret_entry = (struct domain_entry*) table_entry;
76 void domain_run_on_spawnd(struct domain_entry *entry,
77 struct spawnd_state *spawnd)
79 assert(entry != NULL);
80 assert(spawnd != NULL);
81 assert(entry->status == DOMAIN_STATUS_NIL ||
82 entry->status == DOMAIN_STATUS_RUNNING);
84 entry->status = DOMAIN_STATUS_RUNNING;
86 struct domain_spawnd_state *st = (struct domain_spawnd_state*) malloc(
87 sizeof(struct domain_spawnd_state));
88 st->spawnd_state = spawnd;
89 st->next = entry->spawnds;
93 errval_t domain_spawn(struct capref domain_cap, coreid_t core_id)
95 struct domain_entry *entry = NULL;
96 errval_t err = domain_new(domain_cap, &entry);
97 if (err_is_fail(err)) {
104 domain_run_on_spawnd(entry, spawnd_state_get(core_id));
109 errval_t domain_can_span(struct capref domain_cap, coreid_t core_id)
111 struct domain_entry *entry = NULL;
112 errval_t err = domain_get_by_cap(domain_cap, &entry);
113 if (err_is_fail(err)) {
117 assert(entry != NULL);
118 if (entry->status != DOMAIN_STATUS_RUNNING) {
119 return PROC_MGMT_ERR_DOMAIN_NOT_RUNNING;
122 struct domain_spawnd_state *st = entry->spawnds;
124 if (st->spawnd_state->core_id == core_id) {
125 // TODO(razvan): Maybe we want to allow the same domain to span
126 // multiple dispatcher onto the same core?
127 return PROC_MGMT_ERR_ALREADY_SPANNED;
135 errval_t domain_span(struct capref domain_cap, coreid_t core_id)
137 struct domain_entry *entry = NULL;
138 errval_t err = domain_get_by_cap(domain_cap, &entry);
139 if (err_is_fail(err)) {
142 assert(entry != NULL);
144 domain_run_on_spawnd(entry, spawnd_state_get(core_id));
149 void domain_send_stop(struct domain_entry *entry)
151 assert(entry != NULL);
153 struct domain_spawnd_state *st = entry->spawnds;
155 debug_printf("Simulating STOP message to spawnd at binding %p\n",
156 st->spawnd_state->b);