Added: Terminal RPC, Spawn RPC, small abstraction fixes, automatic recv slot allocation in aos_rpc
This commit is contained in:
parent
14063e60be
commit
9750a752c3
@ -1380,6 +1380,7 @@ errors aos AOS_ERR_ {
|
|||||||
failure RPC_ARG_TOO_BIG "RPC argument is too big",
|
failure RPC_ARG_TOO_BIG "RPC argument is too big",
|
||||||
failure RPC_RET_TOO_BIG "RPC return value is too big",
|
failure RPC_RET_TOO_BIG "RPC return value is too big",
|
||||||
failure RPC_UNKNOWN_MSG_TYPE "RPC with unknown message type",
|
failure RPC_UNKNOWN_MSG_TYPE "RPC with unknown message type",
|
||||||
|
failure RPC_PROCESS_UNKNOWN_PID "Requested process name for an unknown PID",
|
||||||
};
|
};
|
||||||
|
|
||||||
// errors NIC driver
|
// errors NIC driver
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
bootdriver /armv8/sbin/boot_armv8_generic
|
bootdriver /armv8/sbin/boot_armv8_generic
|
||||||
cpudriver /armv8/sbin/cpu_a57_qemu loglevel=3 serial=0x9000000 logmask=128
|
cpudriver /armv8/sbin/cpu_a57_qemu loglevel=3 serial=0x9000000 logmask=128
|
||||||
module /armv8/sbin/init
|
module /armv8/sbin/init
|
||||||
module /armv8/sbin/hello Aurel Jan Sandro
|
module /armv8/sbin/hello spawn
|
||||||
module /armv8/sbin/memeater
|
module /armv8/sbin/memeater
|
||||||
|
|
||||||
# End of file, this needs to have a certain length...
|
# End of file, this needs to have a certain length...
|
||||||
|
|||||||
@ -27,6 +27,7 @@ enum rpc_mtype {
|
|||||||
RPC_MTYPE_GET_RAM_CAP,
|
RPC_MTYPE_GET_RAM_CAP,
|
||||||
RPC_MTYPE_SERIAL_GETCHAR,
|
RPC_MTYPE_SERIAL_GETCHAR,
|
||||||
RPC_MTYPE_SERIAL_PUTCHAR,
|
RPC_MTYPE_SERIAL_PUTCHAR,
|
||||||
|
RPC_MTYPE_SERIAL_WRITE,
|
||||||
RPC_MTYPE_PROCESS_SPAWN,
|
RPC_MTYPE_PROCESS_SPAWN,
|
||||||
RPC_MTYPE_PROCESS_GET_NAME,
|
RPC_MTYPE_PROCESS_GET_NAME,
|
||||||
RPC_MTYPE_PROCESS_GET_ALL_PIDS,
|
RPC_MTYPE_PROCESS_GET_ALL_PIDS,
|
||||||
@ -78,6 +79,12 @@ errval_t aos_rpc_serial_getchar(struct aos_rpc *chan, char *retc);
|
|||||||
*/
|
*/
|
||||||
errval_t aos_rpc_serial_putchar(struct aos_rpc *chan, char c);
|
errval_t aos_rpc_serial_putchar(struct aos_rpc *chan, char c);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Send a list of characters to the serial port
|
||||||
|
*/
|
||||||
|
errval_t aos_rpc_serial_write(struct aos_rpc *chan, const char *buf,
|
||||||
|
size_t buf_len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Request that the process manager start a new process
|
* \brief Request that the process manager start a new process
|
||||||
* \arg cmdline the name of the process that needs to be spawned (without a
|
* \arg cmdline the name of the process that needs to be spawned (without a
|
||||||
|
|||||||
@ -63,6 +63,11 @@ struct spawninfo {
|
|||||||
struct aos_rpc_server rpc_server;
|
struct aos_rpc_server rpc_server;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct spawninfo *sawn_get_process_list(void);
|
||||||
|
|
||||||
|
// parse a commandline into arguments
|
||||||
|
void spawn_parse_cmd(char *cmdline, int *argc, char **argv);
|
||||||
|
|
||||||
// Start a child process using the multiboot command line. Fills in si.
|
// Start a child process using the multiboot command line. Fills in si.
|
||||||
errval_t spawn_load_by_name(char *binary_name, struct spawninfo * si,
|
errval_t spawn_load_by_name(char *binary_name, struct spawninfo * si,
|
||||||
domainid_t *pid);
|
domainid_t *pid);
|
||||||
|
|||||||
@ -27,6 +27,11 @@ static errval_t do_aos_rpc(
|
|||||||
) {
|
) {
|
||||||
errval_t err;
|
errval_t err;
|
||||||
|
|
||||||
|
// allocate capability if we expect one and the recv slot is empty
|
||||||
|
if (ret_cap != NULL && rpc->chan->endpoint->k.recv_cptr == 0){
|
||||||
|
lmp_chan_alloc_recv_slot(rpc->chan);
|
||||||
|
}
|
||||||
|
|
||||||
// Send call
|
// Send call
|
||||||
while (true) {
|
while (true) {
|
||||||
err = lmp_chan_send4(rpc->chan, LMP_FLAG_YIELD | LMP_FLAG_SYNC, arg_cap, msg_type, arg_size, arg0, arg1);
|
err = lmp_chan_send4(rpc->chan, LMP_FLAG_YIELD | LMP_FLAG_SYNC, arg_cap, msg_type, arg_size, arg0, arg1);
|
||||||
@ -121,6 +126,36 @@ aos_rpc_serial_putchar(struct aos_rpc *rpc, char c) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// putchar for terminal printing is too slow so we send buffers instead
|
||||||
|
errval_t
|
||||||
|
aos_rpc_serial_write(struct aos_rpc *rpc, const char *buf, size_t buf_len) {
|
||||||
|
errval_t err;
|
||||||
|
|
||||||
|
// split the buffer into chunks for sending
|
||||||
|
while(buf_len > 0) {
|
||||||
|
size_t chunk_len = buf_len;
|
||||||
|
if (chunk_len > RPC_SHARED_SIZE) {
|
||||||
|
chunk_len = RPC_SHARED_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(rpc->shared_mem, buf, chunk_len);
|
||||||
|
|
||||||
|
err = do_aos_rpc(
|
||||||
|
rpc, RPC_MTYPE_SERIAL_WRITE,
|
||||||
|
NULL_CAP, chunk_len, 0, 0,
|
||||||
|
NULL, NULL, NULL, NULL
|
||||||
|
);
|
||||||
|
if (err_is_fail(err)) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf += chunk_len;
|
||||||
|
buf_len -= chunk_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SYS_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
errval_t
|
errval_t
|
||||||
aos_rpc_process_spawn(struct aos_rpc *rpc, char *cmdline,
|
aos_rpc_process_spawn(struct aos_rpc *rpc, char *cmdline,
|
||||||
coreid_t core, domainid_t *newpid) {
|
coreid_t core, domainid_t *newpid) {
|
||||||
@ -153,7 +188,8 @@ aos_rpc_process_get_name(struct aos_rpc *rpc, domainid_t pid, char **name) {
|
|||||||
if (err_is_fail(err)) return err;
|
if (err_is_fail(err)) return err;
|
||||||
*name = malloc(name_len);
|
*name = malloc(name_len);
|
||||||
if (*name == NULL) return LIB_ERR_MALLOC_FAIL;
|
if (*name == NULL) return LIB_ERR_MALLOC_FAIL;
|
||||||
memcpy(name, rpc->shared_mem, name_len);
|
memcpy(*name, rpc->shared_mem, name_len);
|
||||||
|
assert((*name)[name_len] == '\0');
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +200,7 @@ aos_rpc_process_get_all_pids(struct aos_rpc *rpc, domainid_t **pids,
|
|||||||
// (M5): implement process id discovery
|
// (M5): implement process id discovery
|
||||||
size_t ret_len;
|
size_t ret_len;
|
||||||
errval_t err = do_aos_rpc(
|
errval_t err = do_aos_rpc(
|
||||||
rpc, RPC_MTYPE_PROCESS_GET_NAME,
|
rpc, RPC_MTYPE_PROCESS_GET_ALL_PIDS,
|
||||||
NULL_CAP, 0, 0, 0,
|
NULL_CAP, 0, 0, 0,
|
||||||
NULL, &ret_len, NULL, NULL
|
NULL, &ret_len, NULL, NULL
|
||||||
);
|
);
|
||||||
@ -172,7 +208,7 @@ aos_rpc_process_get_all_pids(struct aos_rpc *rpc, domainid_t **pids,
|
|||||||
*pid_count = ret_len / sizeof(**pids);
|
*pid_count = ret_len / sizeof(**pids);
|
||||||
*pids = malloc(ret_len);
|
*pids = malloc(ret_len);
|
||||||
if (*pids == NULL) return LIB_ERR_MALLOC_FAIL;
|
if (*pids == NULL) return LIB_ERR_MALLOC_FAIL;
|
||||||
memcpy(pids, rpc->shared_mem, ret_len);
|
memcpy(*pids, rpc->shared_mem, ret_len);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -100,9 +100,8 @@ static void handle_init_recv(void *arg)
|
|||||||
struct lmp_chan *init_chan = (struct lmp_chan *)arg;
|
struct lmp_chan *init_chan = (struct lmp_chan *)arg;
|
||||||
|
|
||||||
struct lmp_recv_msg msg = LMP_RECV_MSG_INIT;
|
struct lmp_recv_msg msg = LMP_RECV_MSG_INIT;
|
||||||
struct capref cap;
|
|
||||||
|
|
||||||
err = lmp_chan_recv(init_chan, &msg, &cap);
|
err = lmp_chan_recv(init_chan, &msg, NULL);
|
||||||
assert(err_is_ok(err));
|
assert(err_is_ok(err));
|
||||||
|
|
||||||
if (msg.words[0] == SYS_ERR_OK) {
|
if (msg.words[0] == SYS_ERR_OK) {
|
||||||
@ -113,6 +112,32 @@ static void handle_init_recv(void *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO rueegges: allow partial write
|
||||||
|
static size_t aos_terminal_write(const char *buf, size_t len)
|
||||||
|
{
|
||||||
|
errval_t err;
|
||||||
|
struct aos_rpc *rpc = aos_rpc_get_serial_channel();
|
||||||
|
if (rpc == NULL) {
|
||||||
|
debug_printf("Attempted to printf before initializing rpc: %.*s\n", len, buf);
|
||||||
|
USER_PANIC("Make sure to initialize rpc before function barrelfish_libc_glue_init is called.");
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = aos_rpc_serial_write(rpc, buf, len);
|
||||||
|
assert(err_is_ok(err));
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO rueegges: make more efficient?
|
||||||
|
static size_t aos_terminal_read(char *buf, size_t len)
|
||||||
|
{
|
||||||
|
errval_t err;
|
||||||
|
struct aos_rpc *rpc = aos_rpc_get_serial_channel();
|
||||||
|
err = aos_rpc_serial_getchar(rpc, buf);
|
||||||
|
assert(err_is_ok(err));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set libc function pointers */
|
/* Set libc function pointers */
|
||||||
void barrelfish_libc_glue_init(void)
|
void barrelfish_libc_glue_init(void)
|
||||||
{
|
{
|
||||||
@ -120,8 +145,14 @@ void barrelfish_libc_glue_init(void)
|
|||||||
// what we need for that
|
// what we need for that
|
||||||
// TODO: change these to use the user-space serial driver if possible
|
// TODO: change these to use the user-space serial driver if possible
|
||||||
// TODO: set these functions
|
// TODO: set these functions
|
||||||
_libc_terminal_read_func = dummy_terminal_read;
|
// MARKER SHELL: replace functions for init domain or UART driver with non-remote calls
|
||||||
_libc_terminal_write_func = syscall_terminal_write;
|
if(init_domain) {
|
||||||
|
_libc_terminal_read_func = dummy_terminal_read;
|
||||||
|
_libc_terminal_write_func = syscall_terminal_write;
|
||||||
|
} else {
|
||||||
|
_libc_terminal_read_func = aos_terminal_read;
|
||||||
|
_libc_terminal_write_func = aos_terminal_write;
|
||||||
|
}
|
||||||
_libc_exit_func = libc_exit;
|
_libc_exit_func = libc_exit;
|
||||||
_libc_assert_func = libc_assert;
|
_libc_assert_func = libc_assert;
|
||||||
/* morecore func is setup by morecore_init() */
|
/* morecore func is setup by morecore_init() */
|
||||||
|
|||||||
@ -16,19 +16,19 @@ void do_test_spawn(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// wait for 10 seconds but handle events in the mean time
|
// wait for 10 seconds but handle events in the mean time
|
||||||
struct waitset *default_ws = get_default_waitset();
|
// struct waitset *default_ws = get_default_waitset();
|
||||||
struct timespec tt;
|
// struct timespec tt;
|
||||||
clock_gettime(CLOCK_REALTIME, &tt);
|
// clock_gettime(CLOCK_REALTIME, &tt);
|
||||||
long start = time_to_ms(tt);
|
// long start = time_to_ms(tt);
|
||||||
do {
|
// do {
|
||||||
if(err_is_ok(check_for_event(default_ws))){
|
// if(err_is_ok(check_for_event(default_ws))){
|
||||||
CHECK_ERR(event_dispatch(default_ws));
|
// CHECK_ERR(event_dispatch(default_ws));
|
||||||
}
|
// }
|
||||||
clock_gettime(CLOCK_REALTIME, &tt);
|
// clock_gettime(CLOCK_REALTIME, &tt);
|
||||||
} while(time_to_ms(tt) - start < 10000);
|
// } while(time_to_ms(tt) - start < 10000);
|
||||||
|
|
||||||
for(uint i = 0; i < PROCESS_COUNT; ++i) {
|
// for(uint i = 0; i < PROCESS_COUNT; ++i) {
|
||||||
debug_printf("TEST_SPAWN: Killing %u\n", i);
|
// debug_printf("TEST_SPAWN: Killing %u\n", i);
|
||||||
CHECK_ERR(invoke_dispatcher_stop(si[i].dispatcher));
|
// CHECK_ERR(invoke_dispatcher_stop(si[i].dispatcher));
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
#include <aos/aos_rpc.h>
|
#include <aos/aos_rpc.h>
|
||||||
#include <spawn/rpc_server.h>
|
#include <spawn/rpc_server.h>
|
||||||
#include <grading.h>
|
#include <grading.h>
|
||||||
|
#include <spawn/spawn.h>
|
||||||
|
|
||||||
typedef errval_t (*rpc_handler_t)(
|
typedef errval_t (*rpc_handler_t)(
|
||||||
struct aos_rpc_server *rpc,
|
struct aos_rpc_server *rpc,
|
||||||
@ -139,8 +140,8 @@ static errval_t handle_rpc_serial_getchar(
|
|||||||
|
|
||||||
grading_rpc_handler_serial_getchar();
|
grading_rpc_handler_serial_getchar();
|
||||||
|
|
||||||
// TODO
|
// MARKER SHELL: Replace with UART call
|
||||||
*ret0 = 'A';
|
*ret0 = getchar();
|
||||||
|
|
||||||
return LIB_ERR_NOT_IMPLEMENTED;
|
return LIB_ERR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
@ -154,9 +155,27 @@ static errval_t handle_rpc_serial_putchar(
|
|||||||
|
|
||||||
grading_rpc_handler_serial_putchar(c);
|
grading_rpc_handler_serial_putchar(c);
|
||||||
|
|
||||||
// TODO
|
// MARKER SHELL: Replace with UART call
|
||||||
|
putchar(c);
|
||||||
|
|
||||||
return LIB_ERR_NOT_IMPLEMENTED;
|
return SYS_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static errval_t handle_rpc_serial_write(
|
||||||
|
struct aos_rpc_server *rpc,
|
||||||
|
struct capref arg_cap, size_t arg_size, uintptr_t arg0, uintptr_t arg1,
|
||||||
|
struct capref *ret_cap, size_t *ret_size, uintptr_t *ret0, uintptr_t *ret1
|
||||||
|
) {
|
||||||
|
if (arg_size == 0 ) {
|
||||||
|
return ERR_INVALID_ARGS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARKER SHELL: Replace with UART call
|
||||||
|
for (size_t i = 0; i < arg_size; ++i){
|
||||||
|
putchar(((char *)rpc->shared_mem)[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SYS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static errval_t handle_rpc_process_spawn(
|
static errval_t handle_rpc_process_spawn(
|
||||||
@ -172,10 +191,13 @@ static errval_t handle_rpc_process_spawn(
|
|||||||
|
|
||||||
grading_rpc_handler_process_spawn(cmdline, core);
|
grading_rpc_handler_process_spawn(cmdline, core);
|
||||||
|
|
||||||
// TODO
|
struct spawninfo *si = malloc(sizeof(struct spawninfo));
|
||||||
*ret0 = 0;
|
|
||||||
|
|
||||||
return LIB_ERR_NOT_IMPLEMENTED;
|
char *argv[MAX_CMDLINE_ARGS];
|
||||||
|
int argc;
|
||||||
|
spawn_parse_cmd(cmdline, &argc, argv);
|
||||||
|
|
||||||
|
return spawn_load_argv(argc, argv, si, (domainid_t *)ret0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static errval_t handle_rpc_process_get_name(
|
static errval_t handle_rpc_process_get_name(
|
||||||
@ -187,11 +209,28 @@ static errval_t handle_rpc_process_get_name(
|
|||||||
|
|
||||||
grading_rpc_handler_process_get_name(pid);
|
grading_rpc_handler_process_get_name(pid);
|
||||||
|
|
||||||
// TODO
|
// search for the pid
|
||||||
memcpy(rpc->shared_mem, "name", 5);
|
char *name = NULL;
|
||||||
*ret_size = 5;
|
for (struct spawninfo *si = sawn_get_process_list(); si != NULL; si = si->next) {
|
||||||
|
if (si->pid == pid) {
|
||||||
|
name = si->binary_name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return LIB_ERR_NOT_IMPLEMENTED;
|
if (name == NULL) {
|
||||||
|
return AOS_ERR_RPC_PROCESS_UNKNOWN_PID;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t name_len = strlen(name) + 1;
|
||||||
|
if(name_len > RPC_SHARED_SIZE) {
|
||||||
|
return AOS_ERR_RPC_RET_TOO_BIG;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(rpc->shared_mem, name, name_len);
|
||||||
|
*ret_size = name_len;
|
||||||
|
|
||||||
|
return SYS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static errval_t handle_rpc_process_get_all_pids(
|
static errval_t handle_rpc_process_get_all_pids(
|
||||||
@ -201,9 +240,24 @@ static errval_t handle_rpc_process_get_all_pids(
|
|||||||
) {
|
) {
|
||||||
grading_rpc_handler_process_get_all_pids();
|
grading_rpc_handler_process_get_all_pids();
|
||||||
|
|
||||||
// TODO
|
// size in bytes
|
||||||
|
size_t list_size = 0;
|
||||||
|
domainid_t *buf = rpc->shared_mem;
|
||||||
|
|
||||||
return LIB_ERR_NOT_IMPLEMENTED;
|
// get all PIDs that fit into the given space
|
||||||
|
for (struct spawninfo *si = sawn_get_process_list(); si != NULL; si = si->next) {
|
||||||
|
if (list_size + sizeof(domainid_t) > RPC_SHARED_SIZE) {
|
||||||
|
return AOS_ERR_RPC_RET_TOO_BIG;
|
||||||
|
}
|
||||||
|
|
||||||
|
*buf = si->pid;
|
||||||
|
++buf;
|
||||||
|
list_size += sizeof(domainid_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
*ret_size = list_size;
|
||||||
|
|
||||||
|
return SYS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -213,6 +267,7 @@ static rpc_handler_t rpc_handlers[RPC_MTYPE_COUNT] = {
|
|||||||
[RPC_MTYPE_GET_RAM_CAP] = handle_rpc_get_ram_cap,
|
[RPC_MTYPE_GET_RAM_CAP] = handle_rpc_get_ram_cap,
|
||||||
[RPC_MTYPE_SERIAL_GETCHAR] = handle_rpc_serial_getchar,
|
[RPC_MTYPE_SERIAL_GETCHAR] = handle_rpc_serial_getchar,
|
||||||
[RPC_MTYPE_SERIAL_PUTCHAR] = handle_rpc_serial_putchar,
|
[RPC_MTYPE_SERIAL_PUTCHAR] = handle_rpc_serial_putchar,
|
||||||
|
[RPC_MTYPE_SERIAL_WRITE] = handle_rpc_serial_write,
|
||||||
[RPC_MTYPE_PROCESS_SPAWN] = handle_rpc_process_spawn,
|
[RPC_MTYPE_PROCESS_SPAWN] = handle_rpc_process_spawn,
|
||||||
[RPC_MTYPE_PROCESS_GET_NAME] = handle_rpc_process_get_name,
|
[RPC_MTYPE_PROCESS_GET_NAME] = handle_rpc_process_get_name,
|
||||||
[RPC_MTYPE_PROCESS_GET_ALL_PIDS] = handle_rpc_process_get_all_pids,
|
[RPC_MTYPE_PROCESS_GET_ALL_PIDS] = handle_rpc_process_get_all_pids,
|
||||||
|
|||||||
@ -20,7 +20,9 @@ struct spawninfo *spawn_process_list = NULL;
|
|||||||
// TODO: handle "freeing" of PIDs in case we learn how to detect stopped child processes
|
// TODO: handle "freeing" of PIDs in case we learn how to detect stopped child processes
|
||||||
domainid_t spawn_last_pid = 1;
|
domainid_t spawn_last_pid = 1;
|
||||||
|
|
||||||
|
struct spawninfo *sawn_get_process_list(void) {
|
||||||
|
return spawn_process_list;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Set the base address of the .got (Global Offset Table) section of the ELF binary
|
* \brief Set the base address of the .got (Global Offset Table) section of the ELF binary
|
||||||
@ -334,6 +336,13 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si,
|
|||||||
|
|
||||||
// - Initialize the spawn_info struct
|
// - Initialize the spawn_info struct
|
||||||
// TODO
|
// TODO
|
||||||
|
// copy name to spawninfo struct
|
||||||
|
size_t binary_name_len = strlen(argv[0]);
|
||||||
|
si->binary_name = malloc(binary_name_len);
|
||||||
|
if (si->binary_name == NULL) {
|
||||||
|
return LIB_ERR_MALLOC_FAIL;
|
||||||
|
}
|
||||||
|
memcpy(si->binary_name, argv[0], binary_name_len);
|
||||||
|
|
||||||
// - Get the module from the multiboot image
|
// - Get the module from the multiboot image
|
||||||
// and map it (take a look at multiboot.c)
|
// and map it (take a look at multiboot.c)
|
||||||
@ -633,9 +642,23 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si,
|
|||||||
si->pid = ++spawn_last_pid;
|
si->pid = ++spawn_last_pid;
|
||||||
*pid = si->pid;
|
*pid = si->pid;
|
||||||
|
|
||||||
|
// add to process list
|
||||||
|
si->next = spawn_process_list;
|
||||||
|
spawn_process_list = si;
|
||||||
|
|
||||||
return SYS_ERR_OK;
|
return SYS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void spawn_parse_cmd(char *cmdline, int *argc, char **argv){
|
||||||
|
*argc = 0;
|
||||||
|
char *token = strtok(cmdline, " ");
|
||||||
|
while (token != NULL) {
|
||||||
|
argv[*argc] = token;
|
||||||
|
token = strtok(NULL, " ");
|
||||||
|
*argc += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (M2): Implement this function.
|
* (M2): Implement this function.
|
||||||
* \brief Spawn a new dispatcher executing 'binary_name'
|
* \brief Spawn a new dispatcher executing 'binary_name'
|
||||||
@ -665,22 +688,13 @@ errval_t spawn_load_by_name(char *binary_name, struct spawninfo * si,
|
|||||||
// printf("raw_arguments_str: %s\n", raw_arguments_str);
|
// printf("raw_arguments_str: %s\n", raw_arguments_str);
|
||||||
|
|
||||||
// afeer: explode the raw_arguments_str into argv
|
// afeer: explode the raw_arguments_str into argv
|
||||||
char * argv[MAX_CMDLINE_ARGS];
|
char *argv[MAX_CMDLINE_ARGS];
|
||||||
int argc = 0;
|
int argc;
|
||||||
char * token = strtok(raw_arguments_str, " ");
|
spawn_parse_cmd(raw_arguments_str, &argc, argv);
|
||||||
while (token != NULL) {
|
|
||||||
argv[argc] = token;
|
|
||||||
token = strtok(NULL, " ");
|
|
||||||
argc += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - Call spawn_load_argv
|
// - Call spawn_load_argv
|
||||||
err = spawn_load_argv(argc, argv, si, pid);
|
err = spawn_load_argv(argc, argv, si, pid);
|
||||||
if (err_is_fail(err)) return err;
|
if (err_is_fail(err)) return err;
|
||||||
|
|
||||||
// add to process list
|
|
||||||
si->next = spawn_process_list;
|
|
||||||
spawn_process_list = si;
|
|
||||||
|
|
||||||
return SYS_ERR_OK;
|
return SYS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
#include <aos/deferred.h>
|
#include <aos/deferred.h>
|
||||||
|
|
||||||
#define HELLO_CATCH_COMMAND "catch"
|
#define HELLO_CATCH_COMMAND "catch"
|
||||||
|
#define HELLO_SPAWN_COMMAND "spawn"
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@ -40,6 +41,32 @@ int main(int argc, char *argv[])
|
|||||||
err = aos_rpc_send_string(rpc, "Hello World via RPC!");
|
err = aos_rpc_send_string(rpc, "Hello World via RPC!");
|
||||||
if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to send RPC");
|
if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to send RPC");
|
||||||
|
|
||||||
|
// try to spawn a child using rpc
|
||||||
|
if (argc > 1 && !strncmp(argv[1], HELLO_SPAWN_COMMAND, sizeof(HELLO_SPAWN_COMMAND))) {
|
||||||
|
// start process
|
||||||
|
domainid_t pid;
|
||||||
|
rpc = aos_rpc_get_process_channel();
|
||||||
|
err = aos_rpc_process_spawn(rpc, "hello Aurel Jan Sandro", 0, &pid);
|
||||||
|
if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to spawn process");
|
||||||
|
printf("Started a new process!\n");
|
||||||
|
|
||||||
|
// get process name
|
||||||
|
char *name;
|
||||||
|
err = aos_rpc_process_get_name(rpc, pid, &name);
|
||||||
|
if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to get process name");
|
||||||
|
printf("Process Name: %s\n", name);
|
||||||
|
|
||||||
|
// get all PIDs
|
||||||
|
domainid_t *pids;
|
||||||
|
size_t pid_count;
|
||||||
|
err = aos_rpc_process_get_all_pids(rpc, &pids, &pid_count);
|
||||||
|
if (err_is_fail(err)) USER_PANIC_ERR(err, "Failed to get all PIDs");
|
||||||
|
printf("PIDs:\n");
|
||||||
|
for(size_t i = 0; i < pid_count; ++i) {
|
||||||
|
printf(" %lu\n", pids[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if we receive the catch command, RUN!
|
// if we receive the catch command, RUN!
|
||||||
if (argc > 1 && !strncmp(argv[1], HELLO_CATCH_COMMAND, sizeof(HELLO_CATCH_COMMAND))) {
|
if (argc > 1 && !strncmp(argv[1], HELLO_CATCH_COMMAND, sizeof(HELLO_CATCH_COMMAND))) {
|
||||||
int iter = 0;
|
int iter = 0;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user