1/*
2 * Copyright (c) 2009, 2011, ETH Zurich.
3 * All rights reserved.
4 *
5 * This file is distributed under the terms in the attached LICENSE file.
6 * If you do not find this file, copies can be found by writing to:
7 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
8 */
9
10#include <stdlib.h>
11#include <stdio.h>
12#include <string.h>
13#include <assert.h>
14#include <barrelfish/barrelfish.h>
15#include <collections/hash_table.h>
16#include <vfs/vfs.h>
17
18#include "ps.h"
19
20#define HASH_INDEX_BUCKETS 6151
21static collections_hash_table* ps_table = NULL;
22
23static struct ps_entry *entries[MAX_DOMAINS];
24
25errval_t ps_allocate(struct ps_entry *entry, domainid_t *domainid)
26{
27    for(domainid_t i = 1; i < MAX_DOMAINS; i++) {
28        if(entries[i] == NULL) {
29            entries[i] = entry;
30            *domainid = i;
31            entry->domain_id = i;
32            return SYS_ERR_OK;
33        }
34    }
35
36    return SPAWN_ERR_DOMAIN_ALLOCATE;
37}
38
39void ps_remove(domainid_t domain_id)
40{
41    assert(domain_id < MAX_DOMAINS);
42    entries[domain_id] = NULL;
43}
44
45bool ps_exists(domainid_t domain_id)
46{
47    assert(domain_id < MAX_DOMAINS);
48    return entries[domain_id] != NULL ? true : false;
49}
50
51struct ps_entry *ps_get(domainid_t domain_id)
52{
53    if(domain_id >= MAX_DOMAINS) {
54        return NULL;
55    }
56
57    return entries[domain_id];
58}
59
60errval_t ps_hash_domain(struct ps_entry *entry, struct capref domain_cap)
61{
62    entry->domain_cap = domain_cap;
63
64    if (ps_table == NULL) {
65        collections_hash_create_with_buckets(&ps_table, HASH_INDEX_BUCKETS,
66                                             NULL);
67        if (ps_table == NULL) {
68            return SPAWN_ERR_CREATE_DOMAIN_TABLE;
69        }
70    }
71
72    uint64_t key;
73    errval_t err = domain_cap_hash(entry->domain_cap, &key);
74    if (err_is_fail(err)) {
75        return err;
76    }
77
78    collections_hash_insert(ps_table, key, entry);
79
80    return SYS_ERR_OK;
81}
82
83errval_t ps_get_domain(struct capref domain_cap, struct ps_entry **ret_entry,
84                       uint64_t *ret_hash_key)
85{
86    assert(ret_entry != NULL);
87
88    uint64_t key;
89    errval_t err = domain_cap_hash(domain_cap, &key);
90    if (err_is_fail(err)) {
91        return err;
92    }
93
94    void *table_entry = collections_hash_find(ps_table, key);
95    if (table_entry == NULL) {
96        return SPAWN_ERR_DOMAIN_TABLE_FIND;
97    }
98    *ret_entry = (struct ps_entry*) table_entry;
99
100    if (ret_hash_key != NULL) {
101        *ret_hash_key = key;
102    }
103
104    return SYS_ERR_OK;
105}
106
107errval_t ps_release_domain(struct capref domain_cap,
108                           struct ps_entry **ret_entry)
109{
110    assert(ret_entry != NULL);
111
112    uint64_t key;
113    errval_t err = ps_get_domain(domain_cap, ret_entry, &key);
114    if (err_is_fail(err)) {
115        return err;
116    }
117
118    collections_hash_delete(ps_table, key);
119
120    return SYS_ERR_OK;
121}
122