|
|
|
@ -8,6 +8,7 @@
|
|
|
|
|
#include "scheduler.h"
|
|
|
|
|
#include "module.h"
|
|
|
|
|
#include "software_interrupt.h"
|
|
|
|
|
#include "hash.h"
|
|
|
|
|
|
|
|
|
|
extern uint64_t system_start_timestamp;
|
|
|
|
|
|
|
|
|
@ -73,6 +74,9 @@ current_sandbox_start(void)
|
|
|
|
|
//struct module * next_module = sandbox->module->next_module;
|
|
|
|
|
struct module * next_module = sandbox->module->parent_module;
|
|
|
|
|
|
|
|
|
|
static HashTable *sandboxes_request_table = NULL;
|
|
|
|
|
if (sandboxes_request_table == NULL) sandboxes_request_table = create_table();
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Add the client fd to epoll if it is the first or last sandbox in the chain because they
|
|
|
|
|
* need to read and write from/to this fd
|
|
|
|
@ -121,47 +125,59 @@ current_sandbox_start(void)
|
|
|
|
|
} else if (next_module != NULL) {
|
|
|
|
|
/* Generate a new request, copy the current sandbox's output to the next request's buffer, and put it to the global queue */
|
|
|
|
|
ssize_t output_length = sandbox->request_response_data_length - sandbox->request_length;
|
|
|
|
|
char * pre_func_output = (char *)malloc(output_length);
|
|
|
|
|
if (!pre_func_output) {
|
|
|
|
|
char * pre_func_output = NULL;
|
|
|
|
|
char * pre_func_output2 = NULL;
|
|
|
|
|
if (strcmp(next_module->left_module->name, sandbox->module->name) == 0)
|
|
|
|
|
{
|
|
|
|
|
pre_func_output = (char *)malloc(output_length);
|
|
|
|
|
if (!pre_func_output) {
|
|
|
|
|
fprintf(stderr, "Failed to allocate memory for the previous output: %s\n", strerror(errno));
|
|
|
|
|
goto err;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
memcpy(pre_func_output, sandbox->request_response_data + sandbox->request_length, output_length);
|
|
|
|
|
memcpy(pre_func_output, sandbox->request_response_data + sandbox->request_length, output_length);
|
|
|
|
|
}else
|
|
|
|
|
{
|
|
|
|
|
pre_func_output2 = (char *)malloc(output_length);
|
|
|
|
|
if (!pre_func_output2) {
|
|
|
|
|
fprintf(stderr, "Failed to allocate memory for the previous output: %s\n", strerror(errno));
|
|
|
|
|
goto err;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
memcpy(pre_func_output2, sandbox->request_response_data + sandbox->request_length, output_length);
|
|
|
|
|
}
|
|
|
|
|
uint64_t enqueue_timestamp = __getcycles();
|
|
|
|
|
//uint64_t current_rs = enqueue_timestamp - system_start_timestamp;
|
|
|
|
|
//mem_log("time %lu request id:%d executing, name:%s remaining slack %lu\n", current_rs,
|
|
|
|
|
// sandbox->id, sandbox->module->name, sandbox->remaining_slack);
|
|
|
|
|
struct sandbox_request *sandbox_request = NULL;
|
|
|
|
|
static bool left_output_flag = false;
|
|
|
|
|
if (next_module->is_sandboxcreate == false)
|
|
|
|
|
{
|
|
|
|
|
if (strcpy(next_module->left_module->name, sandbox->module->name) == 0)
|
|
|
|
|
sandbox_request =
|
|
|
|
|
sandbox_request_allocate(next_module, false, sandbox->request_length,
|
|
|
|
|
next_module->name, sandbox->client_socket_descriptor,
|
|
|
|
|
(const struct sockaddr *)&sandbox->client_address,
|
|
|
|
|
sandbox->request_arrival_timestamp, enqueue_timestamp,
|
|
|
|
|
sandbox->remaining_slack, true, pre_func_output, pre_func_output2, output_length);
|
|
|
|
|
sandbox_request->id = sandbox->id;
|
|
|
|
|
add_item(sandboxes_request_table, next_module->name, sandbox_request);
|
|
|
|
|
if (pre_func_output != NULL) left_output_flag = true;
|
|
|
|
|
else left_output_flag = false;
|
|
|
|
|
/*change the flag*/
|
|
|
|
|
next_module->is_sandboxcreate = true;
|
|
|
|
|
}else
|
|
|
|
|
{
|
|
|
|
|
sandbox_request = find_value(sandboxes_request_table, next_module->name);
|
|
|
|
|
assert(sandbox_request);
|
|
|
|
|
if (left_output_flag == true)
|
|
|
|
|
{
|
|
|
|
|
struct sandbox_request *sandbox_request =
|
|
|
|
|
sandbox_request_allocate(next_module, false, sandbox->request_length,
|
|
|
|
|
next_module->name, sandbox->client_socket_descriptor,
|
|
|
|
|
(const struct sockaddr *)&sandbox->client_address,
|
|
|
|
|
sandbox->request_arrival_timestamp, enqueue_timestamp,
|
|
|
|
|
sandbox->remaining_slack, true, pre_func_output,NULL, output_length);
|
|
|
|
|
/* TODO: All sandboxs in the chain share the same request id, but sandbox_request_allocate()
|
|
|
|
|
* will busy-wait to generate an unique id, should we optimize it here?
|
|
|
|
|
*/
|
|
|
|
|
sandbox_request->id = sandbox->id;
|
|
|
|
|
sandbox_request->previous_function_output2 = pre_func_output2;
|
|
|
|
|
}else
|
|
|
|
|
{
|
|
|
|
|
struct sandbox_request *sandbox_request =
|
|
|
|
|
sandbox_request_allocate(next_module, false, sandbox->request_length,
|
|
|
|
|
next_module->name, sandbox->client_socket_descriptor,
|
|
|
|
|
(const struct sockaddr *)&sandbox->client_address,
|
|
|
|
|
sandbox->request_arrival_timestamp, enqueue_timestamp,
|
|
|
|
|
sandbox->remaining_slack, true, pre_func_output,NULL, output_length);
|
|
|
|
|
sandbox_request->id = sandbox->id;
|
|
|
|
|
sandbox_request->previous_function_output = pre_func_output;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*the first exed module creat next sandbox_request*/
|
|
|
|
|
next_module->parent_module->is_sandboxcreate == true;
|
|
|
|
|
}else
|
|
|
|
|
{
|
|
|
|
|
//此处需要两个任务:1.读取创建的父节点sandbox_request;2.是否合并上述两个节点的output作为一个input
|
|
|
|
|
remove_item(sandboxes_request_table, next_module->name);
|
|
|
|
|
#ifdef OPT_AVOID_GLOBAL_QUEUE
|
|
|
|
|
/* TODO: The running time of the current sandbox contains the next sandbox's initialization time, does it matter? */
|
|
|
|
|
if (sandbox->absolute_deadline == sandbox_request->absolute_deadline) {
|
|
|
|
|