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>
14 #include <if/spawn_defs.h>
17 #include "spawnd_state.h"
19 #define HASH_INDEX_BUCKETS 6151
20 static collections_hash_table* domain_table = NULL;
22 errval_t domain_new(struct capref domain_cap, struct domain_entry **ret_entry)
24 assert(ret_entry != NULL);
26 struct domain_entry *entry = (struct domain_entry*) malloc(
27 sizeof(struct domain_entry));
29 return LIB_ERR_MALLOC_FAIL;
32 entry->domain_cap = domain_cap;
33 entry->status = DOMAIN_STATUS_NIL;
34 memset(entry->spawnds, 0, sizeof(entry->spawnds));
35 entry->num_spawnds_running = 0;
36 entry->waiters = NULL;
38 if (domain_table == NULL) {
39 collections_hash_create_with_buckets(&domain_table, HASH_INDEX_BUCKETS,
41 if (domain_table == NULL) {
42 return PROC_MGMT_ERR_CREATE_DOMAIN_TABLE;
47 errval_t err = domain_cap_hash(entry->domain_cap, &key);
48 if (err_is_fail(err)) {
52 collections_hash_insert(domain_table, key, entry);
59 errval_t domain_get_by_cap(struct capref domain_cap,
60 struct domain_entry **ret_entry)
62 assert(ret_entry != NULL);
65 errval_t err = domain_cap_hash(domain_cap, &key);
66 if (err_is_fail(err)) {
70 void *table_entry = collections_hash_find(domain_table, key);
71 if (table_entry == NULL) {
72 return PROC_MGMT_ERR_DOMAIN_TABLE_FIND;
74 *ret_entry = (struct domain_entry*) table_entry;
79 void domain_run_on_core(struct domain_entry *entry, coreid_t core_id)
81 assert(entry != NULL);
82 assert(core_id < MAX_COREID);
83 assert(entry->status == DOMAIN_STATUS_NIL ||
84 entry->status == DOMAIN_STATUS_RUNNING);
86 entry->status = DOMAIN_STATUS_RUNNING;
88 entry->spawnds[core_id] = spawnd_state_get(core_id);
89 ++entry->num_spawnds_running;
92 errval_t domain_spawn(struct capref domain_cap, coreid_t core_id)
94 struct domain_entry *entry = NULL;
95 errval_t err = domain_new(domain_cap, &entry);
96 if (err_is_fail(err)) {
103 domain_run_on_core(entry, core_id);
108 errval_t domain_can_span(struct capref domain_cap, coreid_t core_id)
110 struct domain_entry *entry = NULL;
111 errval_t err = domain_get_by_cap(domain_cap, &entry);
112 if (err_is_fail(err)) {
116 assert(entry != NULL);
117 if (entry->status != DOMAIN_STATUS_RUNNING) {
118 return PROC_MGMT_ERR_DOMAIN_NOT_RUNNING;
121 if (entry->spawnds[core_id] != NULL) {
122 // TODO(razvan): Maybe we want to allow the same domain to span multiple
123 // dispatchers onto the same core?
124 return PROC_MGMT_ERR_ALREADY_SPANNED;
130 errval_t domain_span(struct capref domain_cap, coreid_t core_id)
132 struct domain_entry *entry = NULL;
133 errval_t err = domain_get_by_cap(domain_cap, &entry);
134 if (err_is_fail(err)) {
137 assert(entry != NULL);
139 domain_run_on_core(entry, core_id);