#define BENCH_IGNORE_WATERMARK 0XDEADBEEF
-#define BENCH_DUMP_OCTAVE 1
+#define BENCH_DUMP_OCTAVE 0
__BEGIN_DECLS
void bench_init(void);
struct waitset *ws = arg;
assert(ws != NULL);
- debug_printf("Looping on inter-dispatcher message handler\n");
for(;;) {
errval_t err = event_dispatch(ws);
if(err_is_fail(err)) {
acquire_spinlock(&thread_slabs_spinlock);
while (slab_freecount(&thread_slabs) < MAX_THREADS - 1) {
- printf("HEP\n");
struct capref frame;
size_t size;
void *buf;
cFiles = [ "main.c", "service.c", "spawnd_state.c",
"domain.c" ],
addLibraries = libDeps [ "skb", "dist", "lwip",
- "collections", "bench" ],
+ "collections" ],
flounderDefs = [ "monitor", "monitor_blocking" ],
flounderExtraDefs = [ ("monitor_blocking",["rpcclient"]),
("spawn",["rpcclient"]) ],
static struct domain_cap_node *domain_cap_list = NULL;
static uint32_t free_domain_caps = 0;
-#define PROC_MGMT_BENCH 1
-#define PROC_MGMT_BENCH_MIN_RUNS 100
-
-#ifdef PROC_MGMT_BENCH
-#include <bench/bench.h>
-
-static inline cycles_t calculate_time(cycles_t tsc_start, cycles_t tsc_end)
-{
- cycles_t result;
- if (tsc_end < tsc_start) {
- result = (LONG_MAX - tsc_start) + tsc_end - bench_tscoverhead();
- } else {
- result = (tsc_end - tsc_start - bench_tscoverhead());
- }
- return result;
-}
-
-static bench_ctl_t *hash_ctl;
-static uint64_t tscperus;
-#endif
-
inline bool domain_should_refill_caps(void) {
return free_domain_caps == 0;
}
+/**
+ * \brief Allocates a new L2 cnode and fills it with domain capabilities.
+ */
errval_t domain_prealloc_caps(void)
{
- // for (size_t i = 0; i < DOMAIN_CAP_REFILL_COUNT; ++i) {
- // struct domain_cap_node *node = (struct domain_cap_node*) malloc(
- // sizeof(struct domain_cap_node));
- // errval_t err = slot_alloc(&node->domain_cap);
- // if (err_is_fail(err)) {
- // DEBUG_ERR(err, "slot_alloc domain_cap");
- // return err_push(err, PROC_MGMT_ERR_CREATE_DOMAIN_CAP);
- // }
-
- // err = cap_retype(node->domain_cap, cap_procmng, 0, ObjType_Domain, 0, 1);
- // if (err_is_fail(err)) {
- // DEBUG_ERR(err, "cap_retype domain_cap");
- // return err_push(err, PROC_MGMT_ERR_CREATE_DOMAIN_CAP);
- // }
-
- // err = domain_cap_hash(node->domain_cap, &node->hash);
- // if (err_is_fail(err)) {
- // DEBUG_ERR(err, "domain_cap_hash");
- // return err_push(err, PROC_MGMT_ERR_CREATE_DOMAIN_CAP);
- // }
-
- // node->next = domain_cap_list;
- // domain_cap_list = node;
- // ++free_domain_caps;
- // }
-
- // return SYS_ERR_OK;
-
-
struct capref new_cnode_cap;
struct cnoderef new_cnode;
errval_t err = cnode_create_l2(&new_cnode_cap, &new_cnode);
return SYS_ERR_OK;
}
+/**
+ * \brief Returns the next node in the list of available domain caps.
+ */
struct domain_cap_node *next_cap_node(void)
{
assert(domain_cap_list != NULL);
return tmp;
}
+/**
+ * \brief Creates and returns a new domain entry.
+ *
+ * \param cap_node preallocated domain cap node.
+ * \param ret_entry returned domain entry, must be passed in non-NULL.
+ */
errval_t domain_new(struct domain_cap_node *cap_node,
struct domain_entry **ret_entry)
{
entry->waiters = NULL;
if (domain_table == NULL) {
-#ifdef PROC_MGMT_BENCH
- bench_init();
-
- hash_ctl = calloc(1, sizeof(*hash_ctl));
- hash_ctl->mode = BENCH_MODE_FIXEDRUNS;
- hash_ctl->result_dimensions = 1;
- hash_ctl->min_runs = PROC_MGMT_BENCH_MIN_RUNS;
- hash_ctl->data = calloc(hash_ctl->min_runs * hash_ctl->result_dimensions,
- sizeof(*hash_ctl->data));
-
- errval_t err = sys_debug_get_tsc_per_ms(&tscperus);
- assert(err_is_ok(err));
- tscperus /= 1000;
-#endif
collections_hash_create_with_buckets(&domain_table, HASH_INDEX_BUCKETS,
NULL);
if (domain_table == NULL) {
return SYS_ERR_OK;
}
+/**
+ * \brief Returns the domain entry associated with the given domain cap.
+ *
+ * \param domain_cap identifying cap for which to look up the domain entry.
+ * \param returned domain entry, must be passed in non-NULL.
+ */
errval_t domain_get_by_cap(struct capref domain_cap,
struct domain_entry **ret_entry)
{
return SYS_ERR_OK;
}
+/**
+ * \brief Adds a new core to the list of cores where the given domain runs.
+ *
+ * \param entry domain entry to add a new core for.
+ * \param core_id new core running a dispatcher for the domain.
+ */
void domain_run_on_core(struct domain_entry *entry, coreid_t core_id)
{
assert(entry != NULL);
++entry->num_spawnds_resources;
}
+/**
+ * \brief Creates a new domain entry for the given cap node and core.
+ *
+ * \param cap_node preallocated capability node for the new domain.
+ * \param core_id core that runs the new domain.
+ */
errval_t domain_spawn(struct domain_cap_node *cap_node, coreid_t core_id)
{
struct domain_entry *entry = NULL;
return SYS_ERR_OK;
}
+/**
+ * \brief Marks that the domain identified by the given cap spans a new core.
+ *
+ * \param domain_cap identifying capability for the spanning domain.
+ * \param core_id new core which the domain spans.
+ */
errval_t domain_span(struct capref domain_cap, coreid_t core_id)
{
struct domain_entry *entry = NULL;
assert(entry != NULL);
entry->status = DOMAIN_STATUS_STOP_PEND;
}
-// TODO(razvan): domain_exists, domain_remove etc.
#endif // PROC_MGMT_DOMAIN_H
\ No newline at end of file
ClientType_Kill,
ClientType_Exit,
ClientType_Cleanup
- // TODO(razvan): Others?
};
struct pending_spawn {
#include "pending_clients.h"
#include "spawnd_state.h"
+/**
+ * \brief Handler for message add_spawnd, for the local monitor binding.
+ */
static void add_spawnd_handler(struct proc_mgmt_binding *b, coreid_t core_id,
iref_t iref)
{
iref);
}
+/**
+ * \brief Handler for message add_spawnd, for non-monitor bindings.
+ */
static void add_spawnd_handler_non_monitor(struct proc_mgmt_binding *b,
coreid_t core_id, iref_t iref)
{
static bool cleanup_request_sender(struct msg_queue_elem *m);
-
-#define PROC_MGMT_BENCH 1
-#define PROC_MGMT_BENCH_MIN_RUNS 150
-
-#ifdef PROC_MGMT_BENCH
-#include <bench/bench.h>
-
-static inline cycles_t calculate_time(cycles_t tsc_start, cycles_t tsc_end)
-{
- cycles_t result;
- if (tsc_end < tsc_start) {
- result = (LONG_MAX - tsc_start) + tsc_end - bench_tscoverhead();
- } else {
- result = (tsc_end - tsc_start - bench_tscoverhead());
- }
- return result;
-}
-
-static bench_ctl_t *req_ctl_1;
-static bench_ctl_t *req_ctl_2;
-static bench_ctl_t *req_ctl_3;
-static bench_ctl_t *req_ctl_4;
-static bench_ctl_t *req_ctl_5;
-static bench_ctl_t *resp_ctl;
-static uint64_t tscperus;
-#endif
-
+/**
+ * General-purpose handler for replies from spawnd.
+ */
static void spawn_reply_handler(struct spawn_binding *b, errval_t spawn_err)
{
-#ifdef PROC_MGMT_BENCH
- cycles_t tsc_start, tsc_end;
- cycles_t result;
-
- tsc_start = bench_tsc();
-#endif
-
struct pending_client *cl =
(struct pending_client*) spawnd_state_dequeue_recv(b->st);
err = domain_spawn(spawn->cap_node, spawn->core_id);
if (cl->type == ClientType_Spawn) {
resp_err = cl->b->tx_vtbl.spawn_response(cl->b, NOP_CONT,
- err,
- spawn->cap_node->domain_cap);
+ err, spawn->cap_node->domain_cap);
} else {
resp_err = cl->b->tx_vtbl.spawn_with_caps_response(cl->b,
- NOP_CONT,
- err,
- spawn->cap_node->domain_cap);
+ NOP_CONT, err, spawn->cap_node->domain_cap);
}
}
free(spawn);
-
-#ifdef PROC_MGMT_BENCH
- tsc_end = bench_tsc();
- result = calculate_time(tsc_start, tsc_end);
-
- if (resp_ctl != NULL && bench_ctl_add_run(resp_ctl, &result)) {
- bench_ctl_dump_analysis(resp_ctl, 0, "proc_mgmt_resp",
- tscperus);
- bench_ctl_destroy(resp_ctl);
- resp_ctl = NULL;
- }
-#endif
break;
case ClientType_Span:
free(cl);
}
+/**
+ * \brief Handler for sending spawn requests.
+ */
static bool spawn_request_sender(struct msg_queue_elem *m)
{
struct pending_client *cl = (struct pending_client*) m->st;
return true;
}
+/**
+ * \brief Handler for sending span requests.
+ */
static bool span_request_sender(struct msg_queue_elem *m)
{
struct pending_client *cl = (struct pending_client*) m->st;
return true;
}
+/**
+ * \brief Handler for sending kill requests.
+ */
static bool kill_request_sender(struct msg_queue_elem *m)
{
struct pending_client *cl = (struct pending_client*) m->st;
return true;
}
+/**
+ * \brief Handler for sending cleanup requests.
+ */
static bool cleanup_request_sender(struct msg_queue_elem *m)
{
struct pending_client *cl = (struct pending_client*) m->st;
return true;
}
+/**
+ * \brief Common bits of the spawn and spawn_with_caps handlers.
+ */
static errval_t spawn_handler_common(struct proc_mgmt_binding *b,
enum ClientType type,
coreid_t core_id, const char *path,
struct capref inheritcn_cap,
struct capref argcn_cap, uint8_t flags)
{
-#ifdef PROC_MGMT_BENCH
- cycles_t tsc_start, tsc_end;
- cycles_t result;
-
- tsc_start = bench_tsc();
-#endif
if (!spawnd_state_exists(core_id)) {
return PROC_MGMT_ERR_INVALID_SPAWND;
}
-#ifdef PROC_MGMT_BENCH
- tsc_end = bench_tsc();
- result = calculate_time(tsc_start, tsc_end);
- if (req_ctl_1 != NULL && bench_ctl_add_run(req_ctl_1, &result)) {
- bench_ctl_dump_analysis(req_ctl_1, 0, "proc_mgmt_req 1", tscperus);
- bench_ctl_destroy(req_ctl_1);
- req_ctl_1 = NULL;
- }
-#endif
-
-#ifdef PROC_MGMT_BENCH
- tsc_start = bench_tsc();
-#endif
struct spawnd_state *spawnd = spawnd_state_get(core_id);
assert(spawnd != NULL);
struct spawn_binding *cl = spawnd->b;
assert(cl != NULL);
-#ifdef PROC_MGMT_BENCH
- tsc_end = bench_tsc();
- result = calculate_time(tsc_start, tsc_end);
-
- if (req_ctl_2 != NULL && bench_ctl_add_run(req_ctl_2, &result)) {
- bench_ctl_dump_analysis(req_ctl_2, 0, "proc_mgmt_req 2", tscperus);
- bench_ctl_destroy(req_ctl_2);
- req_ctl_2 = NULL;
- }
-#endif
-#ifdef PROC_MGMT_BENCH
- tsc_start = bench_tsc();
-#endif
errval_t err;
if (domain_should_refill_caps()) {
err = domain_prealloc_caps();
struct domain_cap_node *cap_node = next_cap_node();
- // struct capref domain_cap;
- // errval_t err = slot_alloc(&domain_cap);
- // if (err_is_fail(err)) {
- // DEBUG_ERR(err, "slot_alloc domain_cap");
- // return err_push(err, PROC_MGMT_ERR_CREATE_DOMAIN_CAP);
- // }
-#ifdef PROC_MGMT_BENCH
- tsc_end = bench_tsc();
- result = calculate_time(tsc_start, tsc_end);
-
- if (req_ctl_3 != NULL && bench_ctl_add_run(req_ctl_3, &result)) {
- bench_ctl_dump_analysis(req_ctl_3, 0, "proc_mgmt_req 3", tscperus);
- bench_ctl_destroy(req_ctl_3);
- req_ctl_3 = NULL;
- }
-#endif
-
-#ifdef PROC_MGMT_BENCH
- tsc_start = bench_tsc();
-#endif
struct pending_spawn *spawn = (struct pending_spawn*) malloc(
sizeof(struct pending_spawn));
spawn->cap_node = cap_node;
free(msg);
}
-#ifdef PROC_MGMT_BENCH
- tsc_end = bench_tsc();
- result = calculate_time(tsc_start, tsc_end);
-
- if (req_ctl_5 != NULL && bench_ctl_add_run(req_ctl_5, &result)) {
- bench_ctl_dump_analysis(req_ctl_5, 0, "proc_mgmt_req 5", tscperus);
- bench_ctl_destroy(req_ctl_5);
- req_ctl_5 = NULL;
- }
-#endif
-
return SYS_ERR_OK;
}
+/**
+ * \brief Handler for rpc spawn.
+ */
static void spawn_handler(struct proc_mgmt_binding *b, coreid_t core_id,
const char *path, const char *argvbuf,
size_t argvbytes, const char *envbuf, size_t envbytes,
}
}
+/**
+ * \brief Handler for rpc spawn_with_caps.
+ */
static void spawn_with_caps_handler(struct proc_mgmt_binding *b,
coreid_t core_id, const char *path,
const char *argvbuf, size_t argvbytes,
}
}
+/**
+ * \brief Handler for rpc span.
+ */
static void span_handler(struct proc_mgmt_binding *b, struct capref domain_cap,
coreid_t core_id, struct capref vroot,
struct capref dispframe)
}
}
+/**
+ * \brief Common bits of the kill and exit handlers.
+ */
static errval_t kill_handler_common(struct proc_mgmt_binding *b,
struct capref domain_cap,
enum ClientType type,
return SYS_ERR_OK;
}
+/**
+ * \brief Handler for rpc kill.
+ */
static void kill_handler(struct proc_mgmt_binding *b,
struct capref victim_domain_cap)
{
}
}
+/**
+ * \brief Handler for message exit.
+ */
static void exit_handler(struct proc_mgmt_binding *b, struct capref domain_cap,
uint8_t exit_status)
{
// Error or not, there's no client to respond to anymore.
}
+/**
+ * \brief Handler for rpc wait.
+ */
static void wait_handler(struct proc_mgmt_binding *b, struct capref domain_cap)
{
errval_t err, resp_err;
.spawn_with_caps_call = spawn_with_caps_handler,
.span_call = span_handler,
.kill_call = kill_handler,
- // .exit_call = exit_handler,
.exit = exit_handler,
.wait_call = wait_handler
};
.spawn_with_caps_call = spawn_with_caps_handler,
.span_call = span_handler,
.kill_call = kill_handler,
- // .exit_call = exit_handler,
.exit = exit_handler,
.wait_call = wait_handler
};
+/**
+ * \brief Allocates a special LMP endpoint for authenticating with the monitor.
+ */
static errval_t alloc_ep_for_monitor(struct capref *ep)
{
struct proc_mgmt_lmp_binding *lmpb =
errval_t start_service(void)
{
- errval_t err;
-#ifdef PROC_MGMT_BENCH
- bench_init();
-
- req_ctl_1 = calloc(1, sizeof(*req_ctl_1));
- req_ctl_1->mode = BENCH_MODE_FIXEDRUNS;
- req_ctl_1->result_dimensions = 1;
- req_ctl_1->min_runs = PROC_MGMT_BENCH_MIN_RUNS;
- req_ctl_1->data = calloc(req_ctl_1->min_runs * req_ctl_1->result_dimensions,
- sizeof(*req_ctl_1->data));
-
- req_ctl_2 = calloc(1, sizeof(*req_ctl_2));
- req_ctl_2->mode = BENCH_MODE_FIXEDRUNS;
- req_ctl_2->result_dimensions = 1;
- req_ctl_2->min_runs = PROC_MGMT_BENCH_MIN_RUNS;
- req_ctl_2->data = calloc(req_ctl_2->min_runs * req_ctl_2->result_dimensions,
- sizeof(*req_ctl_2->data));
-
- req_ctl_3 = calloc(1, sizeof(*req_ctl_3));
- req_ctl_3->mode = BENCH_MODE_FIXEDRUNS;
- req_ctl_3->result_dimensions = 1;
- req_ctl_3->min_runs = PROC_MGMT_BENCH_MIN_RUNS;
- req_ctl_3->data = calloc(req_ctl_3->min_runs * req_ctl_3->result_dimensions,
- sizeof(*req_ctl_3->data));
-
- req_ctl_4 = calloc(1, sizeof(*req_ctl_4));
- req_ctl_4->mode = BENCH_MODE_FIXEDRUNS;
- req_ctl_4->result_dimensions = 1;
- req_ctl_4->min_runs = PROC_MGMT_BENCH_MIN_RUNS;
- req_ctl_4->data = calloc(req_ctl_4->min_runs * req_ctl_4->result_dimensions,
- sizeof(*req_ctl_4->data));
-
- req_ctl_5 = calloc(1, sizeof(*req_ctl_5));
- req_ctl_5->mode = BENCH_MODE_FIXEDRUNS;
- req_ctl_5->result_dimensions = 1;
- req_ctl_5->min_runs = PROC_MGMT_BENCH_MIN_RUNS;
- req_ctl_5->data = calloc(req_ctl_5->min_runs * req_ctl_5->result_dimensions,
- sizeof(*req_ctl_5->data));
-
- resp_ctl = calloc(1, sizeof(*resp_ctl));
- resp_ctl->mode = BENCH_MODE_FIXEDRUNS;
- resp_ctl->result_dimensions = 1;
- resp_ctl->min_runs = PROC_MGMT_BENCH_MIN_RUNS;
- resp_ctl->data = calloc(resp_ctl->min_runs * resp_ctl->result_dimensions,
- sizeof(*resp_ctl->data));
-
- err = sys_debug_get_tsc_per_ms(&tscperus);
- assert(err_is_ok(err));
- tscperus /= 1000;
-#endif
-
- err = domain_prealloc_caps();
+ errval_t err = domain_prealloc_caps();
if (err_is_fail(err)) {
USER_PANIC_ERR(err_push(err, PROC_MGMT_ERR_CREATE_DOMAIN_CAP),
"domain_prealloc_caps in start_service");
+++ /dev/null
-/**
- * \file
- * \brief Spawn client for the process management service.
- */
-
-/*
- * Copyright (c) 2017, ETH Zurich.
- * All rights reserved.
- *
- * This file is distributed under the terms in the attached LICENSE file.
- * If you do not find this file, copies can be found by writing to:
- * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
- */
-
-#include "spawn_client.h"
-#include "spawnd_state.h"
-
-/**
- * \brief Request the spawn daemon on a specific core to spawn a program
- *
- * \param coreid Core ID on which to spawn the program
- * \param path Absolute path in the file system to an executable
- * image suitable for the given core
- * \param argv Command-line arguments, NULL-terminated
- * \param envp Optional environment, NULL-terminated
- * (pass NULL to inherit)
- * \param inheritcn_cap Cap to a CNode containing capabilities to be inherited
- * \param argcn_cap Cap to a CNode containing capabilities passed as
- * arguments
- * \param flags Flags to spawn
- * \param ret_domain_cap If non-NULL, filled in with domain cap of new domain
- *
- * \bug flags are currently ignored
- */
-errval_t spawn_with_caps(coreid_t core_id, const char *path,
- const char *argvbuf, size_t argvbytes,
- const char *envbuf, size_t envbytes,
- struct capref inheritcn_cap, struct capref argcn_cap,
- uint8_t flags, struct capref *ret_domain_cap)
-{
- errval_t err, msgerr;
-
- if (!spawnd_state_exists(core_id)) {
- USER_PANIC("not connected to spawnd on the requested core");
- }
- struct spawnd_state *state = spawnd_state_get(core_id);
- assert(state != NULL);
- struct spawn_binding *cl = state->b;
- assert(cl != NULL);
-
- struct capref domain_cap;
- err = slot_alloc(&domain_cap);
- if (err_is_fail(err)) {
- USER_PANIC_ERR(err, "slot_alloc domain_cap");
- }
- err = cap_retype(domain_cap, cap_procmng, 0, ObjType_Domain, 0, 1);
- if (err_is_fail(err)) {
- USER_PANIC_ERR(err, "cap_retype domain_cap from cap_procmng");
- }
-
- if (capref_is_null(inheritcn_cap) && capref_is_null(argcn_cap)) {
- err = cl->rpc_tx_vtbl.spawn_proc_mgmt_domain(cl, domain_cap,
- path, argvbuf, argvbytes, envbuf, envbytes, flags, &msgerr);
- } else {
- err = cl->rpc_tx_vtbl.spawn_proc_mgmt_domain_with_caps(cl, domain_cap,
- path, argvbuf, argvbytes, envbuf, envbytes, inheritcn_cap,
- argcn_cap, flags, &msgerr);
- }
- if (err_is_fail(err)) {
- USER_PANIC_ERR(err, "error sending spawn request");
- } else if (err_is_fail(msgerr)) {
- goto out;
- }
-
- if (ret_domain_cap != NULL) {
- *ret_domain_cap = domain_cap;
- }
-
-out:
- return msgerr;
-}
-
-/**
- * \brief Request the spawn daemon on a specific core to spawn a program
- *
- * \param coreid Core ID on which to spawn the program
- * \param path Absolute path in the file system to an executable
- * image suitable for the given core
- * \param argv Command-line arguments, NULL-terminated
- * \param envp Optional environment, NULL-terminated
- * (pass NULL to inherit)
- * \param inheritcn_cap Cap to a CNode containing capabilities to be inherited
- * \param argcn_cap Cap to a CNode containing capabilities passed as
- * arguments
- * \param flags Flags to spawn
- * \param ret_domain_cap If non-NULL, filled in with domain cap of new domain
- *
- * \bug flags are currently ignored
- */
-errval_t spawn(coreid_t core_id, const char *path, const char *argvbuf,
- size_t argvbytes, const char *envbuf, size_t envbytes,
- uint8_t flags, struct capref *ret_domain_cap)
-{
- return spawn_with_caps(core_id, path, argvbuf, argvbytes, envbuf, envbytes,
- NULL_CAP, NULL_CAP, flags, ret_domain_cap);
-}
-
-/**
- * \brief Request the spawn daemon on a specific core to span an existing domain
- *
- * \param domain_cap Identifying capability for the domain to span
- * \param core_id Core ID on which to span
- * \param vroot Vspace root for the dispatcher to span
- * \param dispframe Frame for the dispatcher to span
- */
-errval_t span(struct capref domain_cap, coreid_t core_id, struct capref vroot,
- struct capref dispframe)
-{
- errval_t err, msgerr;
-
- if (!spawnd_state_exists(core_id)) {
- USER_PANIC("not connected to spawnd on the requested core");
- }
- struct spawnd_state *state = spawnd_state_get(core_id);
- assert(state != NULL);
- struct spawn_binding *cl = state->b;
- assert(cl != NULL);
-
- err = cl->rpc_tx_vtbl.span(cl, domain_cap, vroot, dispframe, &msgerr);
- if (err_is_fail(err)) {
- USER_PANIC_ERR(err, "error sending span request");
- }
-
- return msgerr;
-}
+++ /dev/null
-/**
- * \file
- * \brief Spawn client for the process management service.
- */
-
-/*
- * Copyright (c) 2017, ETH Zurich.
- * All rights reserved.
- *
- * This file is distributed under the terms in the attached LICENSE file.
- * If you do not find this file, copies can be found by writing to:
- * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
- */
-
-#ifndef PROC_MGMT_SPAWN_CLIENT_H
-#define PROC_MGMT_SPAWN_CLIENT_H
-
-#include <barrelfish/barrelfish.h>
-
-errval_t spawn_with_caps(coreid_t core_id, const char *path,
- const char *argvbuf, size_t argvbytes,
- const char *envbuf, size_t envbytes,
- struct capref inheritcn_cap, struct capref argcn_cap,
- uint8_t flags, struct capref *ret_domain_cap);
-errval_t spawn(coreid_t core_id, const char *path, const char *argvbuf,
- size_t argvbytes, const char *envbuf, size_t envbytes,
- uint8_t flags, struct capref *ret_domain_cap);
-errval_t span(struct capref domain_cap, coreid_t core_id, struct capref vroot,
- struct capref dispframe);
-
-#endif // PROC_MGMT_SPAWN_CLIENT_H
\ No newline at end of file
static struct spawnd_state *spawnds[MAX_COREID];
+/**
+ * \brief Allocates a state structure for a new spawnd binding.
+ *
+ * \param core_id core where the spawnd newly bound with runs.
+ * \param spawn_binding Flounder binding structure for the spawnd.
+ */
errval_t spawnd_state_alloc(coreid_t core_id, struct spawn_binding *b)
{
spawnds[core_id] = (struct spawnd_state*) malloc(
return SYS_ERR_OK;
}
-void spawnd_state_free(coreid_t core_id)
-{
- if (spawnds[core_id] != NULL) {
- free(spawnds[core_id]);
- }
-}
-
+/**
+ * \brief Returns whether connected to spawnd on the given core.
+ */
inline bool spawnd_state_exists(coreid_t core_id)
{
return spawnds[core_id] != NULL;
}
+/**
+ * \brief Returns the state element for the spawnd on the given core.
+ */
inline struct spawnd_state *spawnd_state_get(coreid_t core_id)
{
return spawnds[core_id];
return q->head == q->tail ? true : false;
}
+/**
+ * \brief Event-based handler for sending requests to spawnd.
+ *
+ * This function pops the next request from the send queue of the targeted
+ * spawnd (wrapped inside arg). It attempts to send the request, re-enqueuing
+ * it at front if sending fails. It then re-registers a new send if the queue
+ * still has pending requests.
+ *
+ * \param arg Wrapper over the spawnd_state structure for the target spawnd.
+ */
static void spawnd_send_handler(void *arg)
{
struct spawnd_state *spawnd = (struct spawnd_state*) arg;
enqueue(&spawnd->recvq, recvm);
} else {
// Send continuation failed, need to re-enqueue message.
- // TODO(razvan): Re-enqueuing at the front of the queue, to preserve
- // original message order. Could a different strategy be preferrable?
enqueue_at_front(q, m);
}
}
}
+/**
+ * \brief Enqueues a new send request event.
+ *
+ * \param spawnd target spawnd to send the request to.
+ * \param msg request to enqueue.
+ */
errval_t spawnd_state_enqueue_send(struct spawnd_state *spawnd,
struct msg_queue_elem *msg)
{
}
}
+/**
+ * \brief Dequeues and returns the next message in a receive queue.
+ *
+ * \param spawnd spawnd instance whose receive queue to pop.
+ */
void *spawnd_state_dequeue_recv(struct spawnd_state *spawnd)
{
struct msg_queue_elem *m = dequeue(&spawnd->recvq);
};
errval_t spawnd_state_alloc(coreid_t core_id, struct spawn_binding *b);
-void spawnd_state_free(coreid_t core_id);
bool spawnd_state_exists(coreid_t core_id);
struct spawnd_state *spawnd_state_get(coreid_t core_id);
[ build application { target = "spawnd",
cFiles = [ "main.c", "service.c", "ps.c" ],
addLibraries = libDeps [ "spawndomain", "elf", "trace", "skb",
- "dist", "vfs", "lwip", "bench" ],
+ "dist", "vfs", "lwip" ],
flounderDefs = [ "monitor", "monitor_blocking" ],
flounderExtraDefs = [ ("monitor_blocking",["rpcclient"]) ],
flounderBindings = [ "spawn" ],
}
}
-#define PROC_MGMT_BENCH 1
-#define PROC_MGMT_BENCH_MIN_RUNS 100
-
-#ifdef PROC_MGMT_BENCH
-#include <bench/bench.h>
-
-static inline cycles_t calculate_time(cycles_t tsc_start, cycles_t tsc_end)
-{
- cycles_t result;
- if (tsc_end < tsc_start) {
- result = (LONG_MAX - tsc_start) + tsc_end - bench_tscoverhead();
- } else {
- result = (tsc_end - tsc_start - bench_tscoverhead());
- }
- return result;
-}
-
-static bench_ctl_t *ctl;
-static uint64_t tscperus;
-#endif
-
static void spawn_request_handler(struct spawn_binding *b,
struct capref procmng_cap,
struct capref domain_cap, const char *path,
const char *envbuf, size_t envbytes,
uint8_t flags)
{
-#ifdef PROC_MGMT_BENCH
- cycles_t tsc_start, tsc_end;
- cycles_t result;
-
- tsc_start = bench_tsc();
-#endif
-
errval_t err, reply_err;
struct capability ret;
err = monitor_cap_identify_remote(procmng_cap, &ret);
if (err_is_fail(reply_err)) {
DEBUG_ERR(err, "failed to send spawn_reply");
}
-
-#ifdef PROC_MGMT_BENCH
- tsc_end = bench_tsc();
- result = calculate_time(tsc_start, tsc_end);
-
- if (ctl != NULL && bench_ctl_add_run(ctl, &result)) {
- bench_ctl_dump_analysis(ctl, 0, "spawnd", tscperus);
- bench_ctl_destroy(ctl);
- ctl = NULL;
- }
-#endif
}
static void span_request_handler(struct spawn_binding *b,
errval_t start_service(void)
{
-#ifdef PROC_MGMT_BENCH
- bench_init();
-
- ctl = calloc(1, sizeof(*ctl));
- ctl->mode = BENCH_MODE_FIXEDRUNS;
- ctl->result_dimensions = 1;
- ctl->min_runs = PROC_MGMT_BENCH_MIN_RUNS;
- ctl->data = calloc(ctl->min_runs * ctl->result_dimensions,
- sizeof(*ctl->data));
-
- errval_t err = sys_debug_get_tsc_per_ms(&tscperus);
- assert(err_is_ok(err));
- tscperus /= 1000;
-#endif
-
return spawn_export(NULL, export_cb, connect_cb, get_default_waitset(),
IDC_EXPORT_FLAGS_DEFAULT);
}