switchless schedule policy and asynchronous calls
This commit is contained in:
parent
db6a49558f
commit
059dc1cc44
559
0050-switchless-schedule-policy.patch
Normal file
559
0050-switchless-schedule-policy.patch
Normal file
@ -0,0 +1,559 @@
|
||||
From 5b5caa5bc583c4a7dec5e3050dae619fa00d8424 Mon Sep 17 00:00:00 2001
|
||||
From: modric <wangyu283@huawei.com>
|
||||
Date: Tue, 18 Oct 2022 21:54:45 +0800
|
||||
Subject: [PATCH 1/4] switchless schedule policy
|
||||
|
||||
Signed-off-by: modric <wangyu283@huawei.com>
|
||||
---
|
||||
inc/common_inc/bit_operation.h | 9 ++
|
||||
inc/common_inc/switchless_defs.h | 49 ++++---
|
||||
inc/host_inc/secgear_defs.h | 1 +
|
||||
inc/host_inc/secgear_uswitchless.h | 12 +-
|
||||
.../gp/itrustee/itrustee_tswitchless.c | 134 ++++++++++++++++--
|
||||
src/host_src/gp/gp_enclave.c | 18 +--
|
||||
src/host_src/gp/gp_enclave.h | 2 +
|
||||
src/host_src/gp/gp_uswitchless.c | 19 +--
|
||||
src/host_src/gp/gp_uswitchless.h | 7 +-
|
||||
9 files changed, 205 insertions(+), 46 deletions(-)
|
||||
|
||||
diff --git a/inc/common_inc/bit_operation.h b/inc/common_inc/bit_operation.h
|
||||
index baa6a1b..ab20121 100644
|
||||
--- a/inc/common_inc/bit_operation.h
|
||||
+++ b/inc/common_inc/bit_operation.h
|
||||
@@ -37,6 +37,15 @@ static inline uint32_t count_tailing_zeroes(uint64_t value)
|
||||
return (uint32_t)__builtin_ctzll(value);
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Returns the number of 1-bits in value.
|
||||
+ */
|
||||
+static inline uint32_t count_ones(uint64_t value)
|
||||
+{
|
||||
+ ASSERT(value != 0);
|
||||
+ return (uint32_t)__builtin_popcountll(value);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Returns the number of leading 0-bits in x, starting at the most significant bit position.
|
||||
* If x is 0, the result is undefined.
|
||||
diff --git a/inc/common_inc/switchless_defs.h b/inc/common_inc/switchless_defs.h
|
||||
index c7e9dfc..84629c3 100644
|
||||
--- a/inc/common_inc/switchless_defs.h
|
||||
+++ b/inc/common_inc/switchless_defs.h
|
||||
@@ -16,28 +16,45 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
+#include "secgear_uswitchless.h"
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SWITCHLESS_BITS_IN_QWORD 64
|
||||
|
||||
-typedef struct {
|
||||
- uint32_t num_uworkers; // number of untrusted (for ocalls) worker threads
|
||||
- uint32_t num_tworkers; // number of trusted (for ecalls) worker threads
|
||||
- uint32_t call_pool_size_qwords; // number of switchless calls pool size (actual number is x 64)
|
||||
- uint32_t num_max_params; // max number of parameters
|
||||
-} sl_task_pool_config_t;
|
||||
+/*
|
||||
+ * sl_task_pool_t free_bit_buf
|
||||
+ * | |
|
||||
+ * v v
|
||||
+ * +-------------------+-+-+--------+-+----------------+-+
|
||||
+ * +---- | task_buf | | | | | | |
|
||||
+ * | +-- | pool_buf |0|1| ... |1| ... |1| normal memory
|
||||
+ * | | +-------------------+-+-+--------+-+----------------+-+
|
||||
+ * | |
|
||||
+ * | | signal_bit_buf
|
||||
+ * | | |
|
||||
+ * | | v
|
||||
+ * | +-> +-------------------+-+-+--------+-+----------------+-+
|
||||
+ * | | | | | | | | |
|
||||
+ * | | cc_sl_config_t |1|0| ... |0| ... |0|
|
||||
+ * +---> +--------+---------++-+-+---+----+-+--+--------+----+-+
|
||||
+ * task[0] | status | func id | retval | params1 | prams2 | ... | shared memory
|
||||
+ * +--------+---------+--------+---------+--------+------+
|
||||
+ * task[n] | ... |
|
||||
+ * +-----------------------------------------------------+
|
||||
+ */
|
||||
|
||||
typedef struct {
|
||||
- char *pool_buf; // switchless task pool control area
|
||||
+ char *pool_buf; // switchless task pool control area, includes configuration area, signal bit area, and task area
|
||||
char *task_buf; // part of pool_buf, stores invoking tasks
|
||||
- uint64_t *free_bit_buf; // idle task flag
|
||||
- uint64_t *signal_bit_buf; // to-be-processed task flag
|
||||
- uint32_t bit_buf_size; // size of each task flag area
|
||||
- uint32_t per_task_size; // size of each task
|
||||
+ uint64_t *free_bit_buf; // length is bit_buf_size, the task indicated by the bit subscript is idle
|
||||
+ uint64_t *signal_bit_buf; // length is bit_buf_size, the task indicated by the bit subscript is to be processed
|
||||
+ uint32_t bit_buf_size; // size of each bit buf in bytes, determined by sl_call_pool_size_qwords in cc_sl_config_t
|
||||
+ uint32_t per_task_size; // size of each task in bytes, for details, see task[0]
|
||||
volatile bool need_stop_tworkers; // indicates whether to stop the trusted proxy thread
|
||||
- sl_task_pool_config_t pool_cfg;
|
||||
+ cc_sl_config_t pool_cfg;
|
||||
} sl_task_pool_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -65,12 +82,12 @@ typedef enum {
|
||||
* Return:
|
||||
* pool size in bytes
|
||||
*/
|
||||
-inline size_t sl_get_pool_buf_len_by_config(sl_task_pool_config_t *pool_cfg)
|
||||
+inline size_t sl_get_pool_buf_len_by_config(cc_sl_config_t *pool_cfg)
|
||||
{
|
||||
- size_t signal_bit_buf_size = pool_cfg->call_pool_size_qwords * sizeof(uint64_t);
|
||||
+ size_t signal_bit_buf_size = pool_cfg->sl_call_pool_size_qwords * sizeof(uint64_t);
|
||||
size_t each_task_size = SL_CALCULATE_PER_TASK_SIZE(pool_cfg);
|
||||
- size_t task_buf_size = each_task_size * pool_cfg->call_pool_size_qwords * SWITCHLESS_BITS_IN_QWORD;
|
||||
- return sizeof(sl_task_pool_config_t) + signal_bit_buf_size + task_buf_size;
|
||||
+ size_t task_buf_size = each_task_size * pool_cfg->sl_call_pool_size_qwords * SWITCHLESS_BITS_IN_QWORD;
|
||||
+ return sizeof(cc_sl_config_t) + signal_bit_buf_size + task_buf_size;
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/inc/host_inc/secgear_defs.h b/inc/host_inc/secgear_defs.h
|
||||
index 4ca11a8..183646d 100644
|
||||
--- a/inc/host_inc/secgear_defs.h
|
||||
+++ b/inc/host_inc/secgear_defs.h
|
||||
@@ -32,6 +32,7 @@ extern "C" {
|
||||
#define CC_MUTEX_UNLOCK(lock) CC_IGNORE(pthread_mutex_unlock(lock))
|
||||
#define CC_COND_INIT(cond, attr) CC_IGNORE(pthread_cond_init(cond, attr))
|
||||
#define CC_COND_SIGNAL(cond) CC_IGNORE(pthread_cond_signal(cond))
|
||||
+#define CC_COND_BROADCAST(cond) CC_IGNORE(pthread_cond_broadcast(cond))
|
||||
#define CC_COND_WAIT(cond, mtx_lock) CC_IGNORE(pthread_cond_wait(cond, mtx_lock))
|
||||
#define CC_COND_DESTROY(cond) CC_IGNORE(pthread_cond_destroy(cond))
|
||||
#define CC_THREAD_ATTR_INIT(attr) CC_IGNORE(pthread_attr_init(attr))
|
||||
diff --git a/inc/host_inc/secgear_uswitchless.h b/inc/host_inc/secgear_uswitchless.h
|
||||
index bff563c..8e21fd9 100644
|
||||
--- a/inc/host_inc/secgear_uswitchless.h
|
||||
+++ b/inc/host_inc/secgear_uswitchless.h
|
||||
@@ -47,6 +47,13 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
+typedef enum {
|
||||
+ /* Worker threads work all the time. */
|
||||
+ WORKERS_POLICY_BUSY,
|
||||
+ /* The worker thread is only woken up when the task arrives and goes to sleep after the task is processed. */
|
||||
+ WORKERS_POLICY_WAKEUP,
|
||||
+ WORKERS_POLICY_MAX
|
||||
+} cc_workers_policy_t;
|
||||
|
||||
typedef struct {
|
||||
/* number of untrusted (for ocalls) worker threads */
|
||||
@@ -72,9 +79,12 @@ typedef struct {
|
||||
* before going to sleep, only for SGX
|
||||
*/
|
||||
uint32_t retries_before_sleep;
|
||||
+
|
||||
+ /* Worker thread scheduling policy, refer to cc_workers_policy_t, only for GP */
|
||||
+ uint64_t workers_policy;
|
||||
} cc_sl_config_t;
|
||||
|
||||
-#define CC_USWITCHLESS_CONFIG_INITIALIZER {1, 1, 1, 16, 0, 0}
|
||||
+#define CC_USWITCHLESS_CONFIG_INITIALIZER {1, 1, 1, 16, 0, 0, WORKERS_POLICY_BUSY}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
diff --git a/src/enclave_src/gp/itrustee/itrustee_tswitchless.c b/src/enclave_src/gp/itrustee/itrustee_tswitchless.c
|
||||
index 5ccb519..3955ff9 100644
|
||||
--- a/src/enclave_src/gp/itrustee/itrustee_tswitchless.c
|
||||
+++ b/src/enclave_src/gp/itrustee/itrustee_tswitchless.c
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
+#include <sys/time.h>
|
||||
#include "secgear_defs.h"
|
||||
#include "switchless_defs.h"
|
||||
#include "bit_operation.h"
|
||||
@@ -55,6 +56,9 @@
|
||||
#define TEESMP_THREAD_ATTR_TASK_ID TEESMP_THREAD_ATTR_TASK_ID_INHERIT
|
||||
#endif
|
||||
|
||||
+static pthread_mutex_t g_sched_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
+static pthread_cond_t g_sched_cond = PTHREAD_COND_INITIALIZER;
|
||||
+
|
||||
static sl_task_pool_t *tswitchless_init_pool(void *pool_buf)
|
||||
{
|
||||
sl_task_pool_t *pool = (sl_task_pool_t *)calloc(1, sizeof(sl_task_pool_t));
|
||||
@@ -63,25 +67,39 @@ static sl_task_pool_t *tswitchless_init_pool(void *pool_buf)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- sl_task_pool_config_t *pool_cfg = (sl_task_pool_config_t *)pool_buf;
|
||||
+ cc_sl_config_t *pool_cfg = (cc_sl_config_t *)pool_buf;
|
||||
|
||||
pool->pool_cfg = *pool_cfg;
|
||||
- pool->bit_buf_size = pool_cfg->call_pool_size_qwords * sizeof(uint64_t);
|
||||
+ pool->bit_buf_size = pool_cfg->sl_call_pool_size_qwords * sizeof(uint64_t);
|
||||
pool->per_task_size = SL_CALCULATE_PER_TASK_SIZE(pool_cfg);
|
||||
|
||||
pool->pool_buf = (char *)pool_buf;
|
||||
- pool->signal_bit_buf = (uint64_t *)(pool->pool_buf + sizeof(sl_task_pool_config_t));
|
||||
+ pool->signal_bit_buf = (uint64_t *)(pool->pool_buf + sizeof(cc_sl_config_t));
|
||||
pool->task_buf = (char *)pool->signal_bit_buf + pool->bit_buf_size;
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
+static bool tswitchless_is_workers_policy_wakeup(cc_sl_config_t *cfg)
|
||||
+{
|
||||
+ return cfg->workers_policy == WORKERS_POLICY_WAKEUP;
|
||||
+}
|
||||
+
|
||||
static void tswitchless_fini_workers(sl_task_pool_t *pool, pthread_t *tids)
|
||||
{
|
||||
int ret;
|
||||
uint32_t thread_num = pool->pool_cfg.num_tworkers;
|
||||
pool->need_stop_tworkers = true;
|
||||
|
||||
+ if (tswitchless_is_workers_policy_wakeup(&(pool->pool_cfg))) {
|
||||
+ thread_num += 1;
|
||||
+
|
||||
+ // Wakes all dormant worker threads and informs it to exit
|
||||
+ CC_MUTEX_LOCK(&g_sched_lock);
|
||||
+ CC_COND_BROADCAST(&g_sched_cond);
|
||||
+ CC_MUTEX_UNLOCK(&g_sched_lock);
|
||||
+ }
|
||||
+
|
||||
for (uint32_t i = 0; i < thread_num; ++i) {
|
||||
if (tids[i] != NULL) {
|
||||
ret = pthread_join(tids[i], NULL);
|
||||
@@ -99,7 +117,7 @@ static inline sl_task_t *tswitchless_get_task_by_index(sl_task_pool_t *pool, int
|
||||
|
||||
static int tswitchless_get_pending_task(sl_task_pool_t *pool)
|
||||
{
|
||||
- int call_pool_size_qwords = (int)pool->pool_cfg.call_pool_size_qwords;
|
||||
+ int call_pool_size_qwords = (int)pool->pool_cfg.sl_call_pool_size_qwords;
|
||||
uint64_t *signal_bit_buf = pool->signal_bit_buf;
|
||||
int start_bit = 0;
|
||||
int end_bit = 0;
|
||||
@@ -156,6 +174,10 @@ static void tswitchless_proc_task(sl_task_t *task)
|
||||
|
||||
static int thread_num = 0;
|
||||
|
||||
+#define TSWITCHLESS_TIMEOUT_IN_USEC 500000
|
||||
+#define TSWITCHLESS_USEC_PER_SEC 1000000
|
||||
+#define TSWITCHLESS_GETTIME_PER_CNT 10000000
|
||||
+
|
||||
static void *tswitchless_thread_routine(void *data)
|
||||
{
|
||||
int thread_index = __atomic_add_fetch(&thread_num, 1, __ATOMIC_ACQ_REL);
|
||||
@@ -165,14 +187,45 @@ static void *tswitchless_thread_routine(void *data)
|
||||
sl_task_t *task_buf = NULL;
|
||||
sl_task_pool_t *pool = (sl_task_pool_t *)data;
|
||||
int processed_count = 0;
|
||||
+ bool is_workers_policy_wakeup = tswitchless_is_workers_policy_wakeup(&(pool->pool_cfg));
|
||||
+ struct timeval tval_before;
|
||||
+ struct timeval tval_after;
|
||||
+ struct timeval duration;
|
||||
+ int count = 0;
|
||||
+ bool timeout = true;
|
||||
|
||||
while (true) {
|
||||
if (pool->need_stop_tworkers) {
|
||||
break;
|
||||
}
|
||||
|
||||
+ count++;
|
||||
task_index = tswitchless_get_pending_task(pool);
|
||||
if (task_index == -1) {
|
||||
+ /*
|
||||
+ * If the scheduling policy is WORKERS_POLICY_WAKEUP, After the task is processed,
|
||||
+ * wait for a period of time before exiting. A new task may arrive immediately.
|
||||
+ * This reduces the performance loss caused by frequent sleep and wakeup between threads.
|
||||
+ */
|
||||
+ if (is_workers_policy_wakeup && count > TSWITCHLESS_GETTIME_PER_CNT) {
|
||||
+ gettimeofday(&tval_after, NULL);
|
||||
+ timersub(&tval_after, &tval_before, &duration);
|
||||
+ timeout =
|
||||
+ (duration.tv_sec * TSWITCHLESS_USEC_PER_SEC + duration.tv_usec) >= TSWITCHLESS_TIMEOUT_IN_USEC;
|
||||
+
|
||||
+ count = 0;
|
||||
+ }
|
||||
+
|
||||
+ if (is_workers_policy_wakeup && timeout) {
|
||||
+ CC_MUTEX_LOCK(&g_sched_lock);
|
||||
+ CC_COND_WAIT(&g_sched_cond, &g_sched_lock);
|
||||
+ CC_MUTEX_UNLOCK(&g_sched_lock);
|
||||
+
|
||||
+ gettimeofday(&tval_before, NULL);
|
||||
+ count = 0;
|
||||
+ timeout = false;
|
||||
+ }
|
||||
+
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -189,12 +242,76 @@ static void *tswitchless_thread_routine(void *data)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+static inline int tswitchless_get_total_pending_task(sl_task_pool_t *pool)
|
||||
+{
|
||||
+ int count = 0;
|
||||
+ int call_pool_size_qwords = (int)pool->pool_cfg.sl_call_pool_size_qwords;
|
||||
+ uint64_t *signal_bit_buf = pool->signal_bit_buf;
|
||||
+ uint64_t element_val = 0;
|
||||
+
|
||||
+ for (int i = 0; i < call_pool_size_qwords; ++i) {
|
||||
+ element_val = *(signal_bit_buf + i);
|
||||
+
|
||||
+ if (element_val == 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ count += count_ones(element_val);
|
||||
+ }
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static void *tswitchless_thread_scheduler(void *data)
|
||||
+{
|
||||
+ SLogTrace("Enter scheduler tworker.");
|
||||
+
|
||||
+ int task_num;
|
||||
+ sl_task_pool_t *pool = (sl_task_pool_t *)data;
|
||||
+
|
||||
+ while (true) {
|
||||
+ if (pool->need_stop_tworkers) {
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ task_num = tswitchless_get_total_pending_task(pool);
|
||||
+ if (task_num == 0) {
|
||||
+ continue;
|
||||
+ } else {
|
||||
+ CC_MUTEX_LOCK(&g_sched_lock);
|
||||
+ CC_COND_BROADCAST(&g_sched_cond);
|
||||
+ CC_MUTEX_UNLOCK(&g_sched_lock);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ SLogTrace("Exit scheduler tworker.");
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+typedef void *(*TSWITCHLESS_THREAD_FUNC)(void *data);
|
||||
+
|
||||
+TSWITCHLESS_THREAD_FUNC tswitchless_get_thread_func(bool is_sched)
|
||||
+{
|
||||
+ if (is_sched) {
|
||||
+ return tswitchless_thread_scheduler;
|
||||
+ }
|
||||
+
|
||||
+ return tswitchless_thread_routine;
|
||||
+}
|
||||
+
|
||||
static pthread_t *tswitchless_init_workers(sl_task_pool_t *pool)
|
||||
{
|
||||
int ret;
|
||||
- sl_task_pool_config_t *pool_cfg = &pool->pool_cfg;
|
||||
+ cc_sl_config_t *pool_cfg = &pool->pool_cfg;
|
||||
+ uint32_t thread_count = pool_cfg->num_tworkers;
|
||||
+ bool is_workers_policy_wakeup = tswitchless_is_workers_policy_wakeup(pool_cfg);
|
||||
+
|
||||
+ if (is_workers_policy_wakeup) {
|
||||
+ thread_count += 1;
|
||||
+ }
|
||||
|
||||
- pthread_t *tids = (pthread_t *)calloc(pool_cfg->num_tworkers, sizeof(pthread_t));
|
||||
+ pthread_t *tids = (pthread_t *)calloc(thread_count, sizeof(pthread_t));
|
||||
if (tids == NULL) {
|
||||
SLogError("Malloc memory for tworkers failed.");
|
||||
return NULL;
|
||||
@@ -214,8 +331,9 @@ static pthread_t *tswitchless_init_workers(sl_task_pool_t *pool)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- for (uint32_t i = 0; i < pool_cfg->num_tworkers; ++i) {
|
||||
- ret = pthread_create(tids + i, &attr, tswitchless_thread_routine, pool);
|
||||
+ for (uint32_t i = 0; i < thread_count; ++i) {
|
||||
+ // If the policy is WORKERS_POLICY_WAKEUP, the first is the scheduling thread.
|
||||
+ ret = pthread_create(tids + i, &attr, tswitchless_get_thread_func(is_workers_policy_wakeup && i == 0), pool);
|
||||
if (ret != 0) {
|
||||
tswitchless_fini_workers(pool, tids);
|
||||
free(tids);
|
||||
diff --git a/src/host_src/gp/gp_enclave.c b/src/host_src/gp/gp_enclave.c
|
||||
index 27952e7..f77cdd8 100644
|
||||
--- a/src/host_src/gp/gp_enclave.c
|
||||
+++ b/src/host_src/gp/gp_enclave.c
|
||||
@@ -10,6 +10,8 @@
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
+#include "gp_enclave.h"
|
||||
+
|
||||
#include <stdint.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
@@ -20,10 +22,8 @@
|
||||
#include <tee_client_type.h>
|
||||
|
||||
#include "secgear_defs.h"
|
||||
-#include "enclave.h"
|
||||
-#include "enclave_internal.h"
|
||||
#include "enclave_log.h"
|
||||
-#include "gp_enclave.h"
|
||||
+#include "secgear_uswitchless.h"
|
||||
#include "register_agent.h"
|
||||
#include "gp_uswitchless.h"
|
||||
#include "gp_shared_memory_defs.h"
|
||||
@@ -370,13 +370,13 @@ cc_enclave_result_t init_uswitchless(cc_enclave_t *enclave, const enclave_featur
|
||||
return CC_ERROR_SWITCHLESS_REINIT;
|
||||
}
|
||||
|
||||
- sl_task_pool_config_t *cfg = (sl_task_pool_config_t *)feature->feature_desc;
|
||||
- if (!uswitchless_is_valid_config(cfg)) {
|
||||
+ cc_sl_config_t cfg = *((cc_sl_config_t *)feature->feature_desc);
|
||||
+ if (!uswitchless_is_valid_config(&cfg)) {
|
||||
return CC_ERROR_BAD_PARAMETERS;
|
||||
}
|
||||
- uswitchless_adjust_config(cfg);
|
||||
+ uswitchless_adjust_config(&cfg);
|
||||
|
||||
- size_t pool_buf_len = sl_get_pool_buf_len_by_config(cfg);
|
||||
+ size_t pool_buf_len = sl_get_pool_buf_len_by_config(&cfg);
|
||||
void *pool_buf = gp_malloc_shared_memory(enclave, pool_buf_len, true);
|
||||
if (pool_buf == NULL) {
|
||||
return CC_ERROR_OUT_OF_MEMORY;
|
||||
@@ -384,10 +384,10 @@ cc_enclave_result_t init_uswitchless(cc_enclave_t *enclave, const enclave_featur
|
||||
(void)memset(pool_buf, 0, pool_buf_len);
|
||||
|
||||
// Fill config
|
||||
- (void)memcpy(pool_buf, cfg, sizeof(sl_task_pool_config_t));
|
||||
+ (void)memcpy(pool_buf, &cfg, sizeof(cc_sl_config_t));
|
||||
|
||||
// Layout task pool
|
||||
- sl_task_pool_t *pool = uswitchless_create_task_pool(pool_buf, cfg);
|
||||
+ sl_task_pool_t *pool = uswitchless_create_task_pool(pool_buf, &cfg);
|
||||
if (pool == NULL) {
|
||||
(void)gp_free_shared_memory(enclave, pool_buf);
|
||||
return CC_ERROR_OUT_OF_MEMORY;
|
||||
diff --git a/src/host_src/gp/gp_enclave.h b/src/host_src/gp/gp_enclave.h
|
||||
index e788ed3..2fdfc99 100644
|
||||
--- a/src/host_src/gp/gp_enclave.h
|
||||
+++ b/src/host_src/gp/gp_enclave.h
|
||||
@@ -15,6 +15,8 @@
|
||||
|
||||
#include "tee_client_api.h"
|
||||
#include "switchless_defs.h"
|
||||
+#include "enclave.h"
|
||||
+#include "enclave_internal.h"
|
||||
|
||||
enum
|
||||
{
|
||||
diff --git a/src/host_src/gp/gp_uswitchless.c b/src/host_src/gp/gp_uswitchless.c
|
||||
index 8db756e..f1288c2 100644
|
||||
--- a/src/host_src/gp/gp_uswitchless.c
|
||||
+++ b/src/host_src/gp/gp_uswitchless.c
|
||||
@@ -34,19 +34,20 @@
|
||||
#define SWITCHLESS_DEFAULT_TWORKERS 8
|
||||
#define SWITCHLESS_DEFAULT_POOL_SIZE_QWORDS 1
|
||||
|
||||
-bool uswitchless_is_valid_config(sl_task_pool_config_t *cfg)
|
||||
+bool uswitchless_is_valid_config(cc_sl_config_t *cfg)
|
||||
{
|
||||
if ((cfg->num_uworkers > SWITCHLESS_MAX_UWORKERS) ||
|
||||
(cfg->num_tworkers > SWITCHLESS_MAX_TWORKERS) ||
|
||||
(cfg->num_max_params > SWITCHLESS_MAX_PARAMETER_NUM) ||
|
||||
- (cfg->call_pool_size_qwords > SWITCHLESS_MAX_POOL_SIZE_QWORDS)) {
|
||||
+ (cfg->sl_call_pool_size_qwords > SWITCHLESS_MAX_POOL_SIZE_QWORDS) ||
|
||||
+ (cfg->workers_policy >= WORKERS_POLICY_MAX)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
-void uswitchless_adjust_config(sl_task_pool_config_t *cfg)
|
||||
+void uswitchless_adjust_config(cc_sl_config_t *cfg)
|
||||
{
|
||||
if (cfg->num_uworkers == 0) {
|
||||
cfg->num_uworkers = SWITCHLESS_DEFAULT_UWORKERS;
|
||||
@@ -56,14 +57,14 @@ void uswitchless_adjust_config(sl_task_pool_config_t *cfg)
|
||||
cfg->num_tworkers = SWITCHLESS_DEFAULT_TWORKERS;
|
||||
}
|
||||
|
||||
- if (cfg->call_pool_size_qwords == 0) {
|
||||
- cfg->call_pool_size_qwords = SWITCHLESS_DEFAULT_POOL_SIZE_QWORDS;
|
||||
+ if (cfg->sl_call_pool_size_qwords == 0) {
|
||||
+ cfg->sl_call_pool_size_qwords = SWITCHLESS_DEFAULT_POOL_SIZE_QWORDS;
|
||||
}
|
||||
}
|
||||
|
||||
-sl_task_pool_t *uswitchless_create_task_pool(void *pool_buf, sl_task_pool_config_t *pool_cfg)
|
||||
+sl_task_pool_t *uswitchless_create_task_pool(void *pool_buf, cc_sl_config_t *pool_cfg)
|
||||
{
|
||||
- size_t bit_buf_size = pool_cfg->call_pool_size_qwords * sizeof(uint64_t);
|
||||
+ size_t bit_buf_size = pool_cfg->sl_call_pool_size_qwords * sizeof(uint64_t);
|
||||
sl_task_pool_t *pool = (sl_task_pool_t *)calloc(sizeof(sl_task_pool_t) + bit_buf_size, sizeof(char));
|
||||
if (pool == NULL) {
|
||||
return NULL;
|
||||
@@ -76,7 +77,7 @@ sl_task_pool_t *uswitchless_create_task_pool(void *pool_buf, sl_task_pool_config
|
||||
pool->pool_buf = (char *)pool_buf;
|
||||
pool->free_bit_buf = (uint64_t *)((char *)pool + sizeof(sl_task_pool_t));
|
||||
(void)memset(pool->free_bit_buf, 0xFF, bit_buf_size);
|
||||
- pool->signal_bit_buf = (uint64_t *)(pool->pool_buf + sizeof(sl_task_pool_config_t));
|
||||
+ pool->signal_bit_buf = (uint64_t *)(pool->pool_buf + sizeof(cc_sl_config_t));
|
||||
pool->task_buf = (char *)pool->signal_bit_buf + pool->bit_buf_size;
|
||||
|
||||
return pool;
|
||||
@@ -99,7 +100,7 @@ bool uswitchless_is_valid_param_num(cc_enclave_t *enclave, uint32_t argc)
|
||||
int uswitchless_get_idle_task_index(cc_enclave_t *enclave)
|
||||
{
|
||||
sl_task_pool_t *pool = USWITCHLESS_TASK_POOL(enclave);
|
||||
- int call_pool_size_qwords = (int)pool->pool_cfg.call_pool_size_qwords;
|
||||
+ int call_pool_size_qwords = (int)pool->pool_cfg.sl_call_pool_size_qwords;
|
||||
uint64_t *free_bit_buf = pool->free_bit_buf;
|
||||
int start_bit = 0;
|
||||
int end_bit = 0;
|
||||
diff --git a/src/host_src/gp/gp_uswitchless.h b/src/host_src/gp/gp_uswitchless.h
|
||||
index e435ad1..4d957ce 100644
|
||||
--- a/src/host_src/gp/gp_uswitchless.h
|
||||
+++ b/src/host_src/gp/gp_uswitchless.h
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <stdbool.h>
|
||||
#include "enclave.h"
|
||||
#include "switchless_defs.h"
|
||||
+#include "secgear_uswitchless.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -32,7 +33,7 @@ extern "C" {
|
||||
* true: valid
|
||||
* false: invalid
|
||||
*/
|
||||
-bool uswitchless_is_valid_config(sl_task_pool_config_t *cfg);
|
||||
+bool uswitchless_is_valid_config(cc_sl_config_t *cfg);
|
||||
|
||||
/*
|
||||
* Summary: Adjusting default configurations
|
||||
@@ -40,7 +41,7 @@ bool uswitchless_is_valid_config(sl_task_pool_config_t *cfg);
|
||||
* cfg: configuration information of the task pool
|
||||
* Return: NA
|
||||
*/
|
||||
-void uswitchless_adjust_config(sl_task_pool_config_t *cfg);
|
||||
+void uswitchless_adjust_config(cc_sl_config_t *cfg);
|
||||
|
||||
/*
|
||||
* Summary: initializing the switchless invoking task pool
|
||||
@@ -49,7 +50,7 @@ void uswitchless_adjust_config(sl_task_pool_config_t *cfg);
|
||||
* pool_cfg: configuration information of the task pool
|
||||
* Return: NA
|
||||
*/
|
||||
-sl_task_pool_t *uswitchless_create_task_pool(void *pool_buf, sl_task_pool_config_t *pool_cfg);
|
||||
+sl_task_pool_t *uswitchless_create_task_pool(void *pool_buf, cc_sl_config_t *pool_cfg);
|
||||
|
||||
/*
|
||||
* Summary: obtains the index of an idle task area from specified enclave
|
||||
--
|
||||
2.27.0
|
||||
|
||||
515
0051-asynchronous-switchless.patch
Normal file
515
0051-asynchronous-switchless.patch
Normal file
@ -0,0 +1,515 @@
|
||||
From f73e925c5bd78dff9c6398f62386c86d1e7aaf01 Mon Sep 17 00:00:00 2001
|
||||
From: modric <wangyu283@huawei.com>
|
||||
Date: Wed, 9 Nov 2022 15:14:08 +0800
|
||||
Subject: [PATCH 2/4] asynchronous switchless
|
||||
|
||||
---
|
||||
inc/common_inc/switchless_defs.h | 3 +-
|
||||
inc/host_inc/enclave.h | 13 ++++++++
|
||||
inc/host_inc/enclave_internal.h | 12 ++++---
|
||||
inc/host_inc/status.h | 4 ++-
|
||||
src/host_src/enclave.c | 18 ++++++++++
|
||||
src/host_src/gp/gp_enclave.c | 57 ++++++++++++++++++++++++++++----
|
||||
src/host_src/gp/gp_uswitchless.c | 44 +++++++++++++++++++++---
|
||||
src/host_src/gp/gp_uswitchless.h | 35 ++++++++++++++++----
|
||||
tools/codegener/Genheader.ml | 29 +++++++++++++++-
|
||||
tools/codegener/Genuntrust.ml | 54 ++++++++++++++++++++++++++++--
|
||||
10 files changed, 242 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/inc/common_inc/switchless_defs.h b/inc/common_inc/switchless_defs.h
|
||||
index 84629c3..b525df0 100644
|
||||
--- a/inc/common_inc/switchless_defs.h
|
||||
+++ b/inc/common_inc/switchless_defs.h
|
||||
@@ -59,7 +59,8 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
volatile uint32_t status;
|
||||
- uint32_t func_id;
|
||||
+ uint16_t func_id;
|
||||
+ uint16_t retval_size;
|
||||
volatile uint64_t ret_val;
|
||||
uint64_t params[0];
|
||||
} sl_task_t;
|
||||
diff --git a/inc/host_inc/enclave.h b/inc/host_inc/enclave.h
|
||||
index 0dde8c3..94aedf4 100644
|
||||
--- a/inc/host_inc/enclave.h
|
||||
+++ b/inc/host_inc/enclave.h
|
||||
@@ -87,6 +87,19 @@ CC_API_SPEC cc_enclave_result_t cc_enclave_create(
|
||||
|
||||
CC_API_SPEC cc_enclave_result_t cc_enclave_destroy(cc_enclave_t *context);
|
||||
|
||||
+/*
|
||||
+ * Summary: Obtains the result of the switchless asynchronous invoking task
|
||||
+ * Parameters:
|
||||
+ * enclave: enclave
|
||||
+ * task_id: id of an asynchronous invoking task
|
||||
+ * retval: accepts the return value, NULL is required for functions of the void type or the return value is ignored
|
||||
+ * Return:
|
||||
+ * CC_SUCCESS, success;
|
||||
+ * CC_ERROR_SWITCHLESS_ASYNC_TASK_UNFINISHED, the asynchronous invoking task is not completed;
|
||||
+ * others failed.
|
||||
+ */
|
||||
+CC_API_SPEC cc_enclave_result_t cc_sl_get_async_result(cc_enclave_t *enclave, int task_id, void *retval);
|
||||
+
|
||||
/*automatic file generation required: aligned bytes*/
|
||||
#define ALIGNMENT_SIZE (2 * sizeof(void*))
|
||||
|
||||
diff --git a/inc/host_inc/enclave_internal.h b/inc/host_inc/enclave_internal.h
|
||||
index 5a8af38..a66d1a3 100644
|
||||
--- a/inc/host_inc/enclave_internal.h
|
||||
+++ b/inc/host_inc/enclave_internal.h
|
||||
@@ -31,7 +31,8 @@ typedef enum _enclave_state {
|
||||
} enclave_state_t;
|
||||
|
||||
typedef struct {
|
||||
- uint32_t func_id;
|
||||
+ uint16_t func_id;
|
||||
+ uint16_t retval_size;
|
||||
uint32_t argc;
|
||||
void *args;
|
||||
} sl_ecall_func_info_t;
|
||||
@@ -66,10 +67,11 @@ struct cc_enclave_ops {
|
||||
const void *ocall_table);
|
||||
|
||||
/* switchless ecall */
|
||||
- cc_enclave_result_t (*cc_sl_ecall_enclave)(cc_enclave_t *enclave,
|
||||
- void *retval,
|
||||
- size_t retval_size,
|
||||
- sl_ecall_func_info_t *func_info);
|
||||
+ cc_enclave_result_t (*cc_sl_ecall_enclave)(cc_enclave_t *enclave, void *retval, sl_ecall_func_info_t *func_info);
|
||||
+
|
||||
+ /* switchless async ecall */
|
||||
+ cc_enclave_result_t (*cc_sl_async_ecall)(cc_enclave_t *enclave, int *task_id, sl_ecall_func_info_t *func_info);
|
||||
+ cc_enclave_result_t (*cc_sl_async_ecall_get_result)(cc_enclave_t *enclave, int task_id, void *retval);
|
||||
|
||||
/* shared memory */
|
||||
void *(*cc_malloc_shared_memory)(cc_enclave_t *enclave, size_t size, bool is_control_buf);
|
||||
diff --git a/inc/host_inc/status.h b/inc/host_inc/status.h
|
||||
index 15de9d1..4f982f8 100644
|
||||
--- a/inc/host_inc/status.h
|
||||
+++ b/inc/host_inc/status.h
|
||||
@@ -165,7 +165,9 @@ typedef enum _enclave_result_t
|
||||
CC_ERROR_SHARED_MEMORY_REPEAT_REGISTER, /* The shared memory is repeatedly registered */
|
||||
CC_ERROR_SHARED_MEMORY_START_ADDR_INVALID, /* Invalid start address of the shared memory */
|
||||
CC_ERROR_SHARED_MEMORY_NOT_REGISTERED, /* Unregistered shared memory */
|
||||
- CC_ERROR_ADDRESS_UNACCESSABLE, /* Memory address is not within enclave */
|
||||
+ CC_ERROR_ADDRESS_UNACCESSABLE, /* Memory address is not within enclave */
|
||||
+ CC_ERROR_SWITCHLESS_INVALID_TASK_ID, /* Invalid invoking task ID */
|
||||
+ CC_ERROR_SWITCHLESS_ASYNC_TASK_UNFINISHED, /* The asynchronous invoking task is not completed */
|
||||
CC_MAXIMUM_ERROR,
|
||||
} cc_enclave_result_t;
|
||||
|
||||
diff --git a/src/host_src/enclave.c b/src/host_src/enclave.c
|
||||
index 2e6a28a..d8b7d35 100644
|
||||
--- a/src/host_src/enclave.c
|
||||
+++ b/src/host_src/enclave.c
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "enclave.h"
|
||||
#include "enclave_log.h"
|
||||
#include "enclave_internal.h"
|
||||
+#include "secgear_defs.h"
|
||||
|
||||
extern list_ops_management g_list_ops;
|
||||
|
||||
@@ -313,3 +314,20 @@ cc_enclave_result_t cc_enclave_destroy(cc_enclave_t *context)
|
||||
|
||||
return CC_SUCCESS;
|
||||
}
|
||||
+
|
||||
+cc_enclave_result_t cc_sl_get_async_result(cc_enclave_t *enclave, int task_id, void *retval)
|
||||
+{
|
||||
+ cc_enclave_result_t ret;
|
||||
+
|
||||
+ if (enclave == NULL || task_id < 0 || !enclave->used_flag) {
|
||||
+ return CC_ERROR_BAD_PARAMETERS;
|
||||
+ }
|
||||
+
|
||||
+ CC_RWLOCK_LOCK_RD(&enclave->rwlock);
|
||||
+
|
||||
+ ret = enclave->list_ops_node->ops_desc->ops->cc_sl_async_ecall_get_result(enclave, task_id, retval);
|
||||
+
|
||||
+ CC_RWLOCK_UNLOCK(&enclave->rwlock);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/host_src/gp/gp_enclave.c b/src/host_src/gp/gp_enclave.c
|
||||
index f77cdd8..5345973 100644
|
||||
--- a/src/host_src/gp/gp_enclave.c
|
||||
+++ b/src/host_src/gp/gp_enclave.c
|
||||
@@ -817,10 +817,7 @@ done:
|
||||
return result;
|
||||
}
|
||||
|
||||
-cc_enclave_result_t cc_sl_enclave_call_function(cc_enclave_t *enclave,
|
||||
- void *retval,
|
||||
- size_t retval_size,
|
||||
- sl_ecall_func_info_t *func_info)
|
||||
+cc_enclave_result_t cc_sl_enclave_call_function(cc_enclave_t *enclave, void *retval, sl_ecall_func_info_t *func_info)
|
||||
{
|
||||
if (!uswitchless_is_switchless_enabled(enclave)) {
|
||||
return CC_ERROR_SWITCHLESS_DISABLED;
|
||||
@@ -835,19 +832,67 @@ cc_enclave_result_t cc_sl_enclave_call_function(cc_enclave_t *enclave,
|
||||
return CC_ERROR_SWITCHLESS_TASK_POOL_FULL;
|
||||
}
|
||||
|
||||
- uswitchless_fill_task(enclave, task_index, func_info->func_id, func_info->argc, func_info->args);
|
||||
+ uswitchless_fill_task(enclave, task_index, func_info->func_id, func_info->retval_size, func_info->argc,
|
||||
+ func_info->args);
|
||||
uswitchless_submit_task(enclave, task_index);
|
||||
- cc_enclave_result_t ret = uswitchless_get_task_result(enclave, task_index, retval, retval_size);
|
||||
+ cc_enclave_result_t ret = uswitchless_get_task_result(enclave, task_index, retval);
|
||||
uswitchless_put_idle_task_by_index(enclave, task_index);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
+cc_enclave_result_t cc_sl_async_ecall(cc_enclave_t *enclave, int *task_id, sl_ecall_func_info_t *func_info)
|
||||
+{
|
||||
+ if (task_id == NULL) {
|
||||
+ return CC_ERROR_BAD_PARAMETERS;
|
||||
+ }
|
||||
+
|
||||
+ if (!uswitchless_is_switchless_enabled(enclave)) {
|
||||
+ return CC_ERROR_SWITCHLESS_DISABLED;
|
||||
+ }
|
||||
+
|
||||
+ if (!uswitchless_is_valid_param_num(enclave, func_info->argc)) {
|
||||
+ return CC_ERROR_SWITCHLESS_INVALID_ARG_NUM;
|
||||
+ }
|
||||
+
|
||||
+ int task_index = uswitchless_get_idle_task_index(enclave);
|
||||
+ if (task_index < 0) {
|
||||
+ return CC_ERROR_SWITCHLESS_TASK_POOL_FULL;
|
||||
+ }
|
||||
+
|
||||
+ uswitchless_fill_task(enclave, task_index, func_info->func_id, func_info->retval_size, func_info->argc,
|
||||
+ func_info->args);
|
||||
+ uswitchless_submit_task(enclave, task_index);
|
||||
+ *task_id = task_index;
|
||||
+
|
||||
+ return CC_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+cc_enclave_result_t cc_sl_async_ecall_check_result(cc_enclave_t *enclave, int task_id, void *retval)
|
||||
+{
|
||||
+ if (!uswitchless_is_switchless_enabled(enclave)) {
|
||||
+ return CC_ERROR_SWITCHLESS_DISABLED;
|
||||
+ }
|
||||
+
|
||||
+ if (!uswitchless_is_valid_task_index(enclave, task_id)) {
|
||||
+ return CC_ERROR_SWITCHLESS_INVALID_TASK_ID;
|
||||
+ }
|
||||
+
|
||||
+ cc_enclave_result_t ret = uswitchless_get_async_task_result(enclave, task_id, retval);
|
||||
+ if (ret != CC_ERROR_SWITCHLESS_ASYNC_TASK_UNFINISHED) {
|
||||
+ uswitchless_put_idle_task_by_index(enclave, task_id);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
const struct cc_enclave_ops g_ops = {
|
||||
.cc_create_enclave = _gp_create,
|
||||
.cc_destroy_enclave = _gp_destroy,
|
||||
.cc_ecall_enclave = cc_enclave_call_function,
|
||||
.cc_sl_ecall_enclave = cc_sl_enclave_call_function,
|
||||
+ .cc_sl_async_ecall = cc_sl_async_ecall,
|
||||
+ .cc_sl_async_ecall_get_result = cc_sl_async_ecall_check_result,
|
||||
.cc_malloc_shared_memory = gp_malloc_shared_memory,
|
||||
.cc_free_shared_memory = gp_free_shared_memory,
|
||||
.cc_register_shared_memory = gp_register_shared_memory,
|
||||
diff --git a/src/host_src/gp/gp_uswitchless.c b/src/host_src/gp/gp_uswitchless.c
|
||||
index f1288c2..2a315ea 100644
|
||||
--- a/src/host_src/gp/gp_uswitchless.c
|
||||
+++ b/src/host_src/gp/gp_uswitchless.c
|
||||
@@ -97,6 +97,21 @@ bool uswitchless_is_valid_param_num(cc_enclave_t *enclave, uint32_t argc)
|
||||
return argc <= USWITCHLESS_TASK_POOL(enclave)->pool_cfg.num_max_params;
|
||||
}
|
||||
|
||||
+bool uswitchless_is_valid_task_index(cc_enclave_t *enclave, int task_index)
|
||||
+{
|
||||
+ sl_task_pool_t *pool = USWITCHLESS_TASK_POOL(enclave);
|
||||
+ int task_total = pool->pool_cfg.sl_call_pool_size_qwords * SWITCHLESS_BITS_IN_QWORD;
|
||||
+
|
||||
+ if (task_index < 0 || task_index >= task_total) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ int i = task_index / SWITCHLESS_BITS_IN_QWORD;
|
||||
+ int j = task_index % SWITCHLESS_BITS_IN_QWORD;
|
||||
+
|
||||
+ return !((*(pool->free_bit_buf + i)) & (1UL << j));
|
||||
+}
|
||||
+
|
||||
int uswitchless_get_idle_task_index(cc_enclave_t *enclave)
|
||||
{
|
||||
sl_task_pool_t *pool = USWITCHLESS_TASK_POOL(enclave);
|
||||
@@ -144,11 +159,13 @@ static inline sl_task_t *uswitchless_get_task_by_index(cc_enclave_t *enclave, in
|
||||
return (sl_task_t *)(pool->task_buf + task_index * pool->per_task_size);
|
||||
}
|
||||
|
||||
-void uswitchless_fill_task(cc_enclave_t *enclave, int task_index, uint32_t func_id, uint32_t argc, const void *args)
|
||||
+void uswitchless_fill_task(cc_enclave_t *enclave, int task_index, uint16_t func_id, uint16_t retval_size,
|
||||
+ uint32_t argc, const void *args)
|
||||
{
|
||||
sl_task_t *task = uswitchless_get_task_by_index(enclave, task_index);
|
||||
|
||||
task->func_id = func_id;
|
||||
+ task->retval_size = retval_size;
|
||||
__atomic_store_n(&task->status, SL_TASK_INIT, __ATOMIC_RELEASE);
|
||||
memcpy(&task->params[0], args, sizeof(uint64_t) * argc);
|
||||
}
|
||||
@@ -165,7 +182,7 @@ void uswitchless_submit_task(cc_enclave_t *enclave, int task_index)
|
||||
|
||||
#define CA_TIMEOUT_IN_SEC 60
|
||||
#define CA_GETTIME_PER_CNT 100000000
|
||||
-cc_enclave_result_t uswitchless_get_task_result(cc_enclave_t *enclave, int task_index, void *retval, size_t retval_size)
|
||||
+cc_enclave_result_t uswitchless_get_task_result(cc_enclave_t *enclave, int task_index, void *retval)
|
||||
{
|
||||
sl_task_t *task = uswitchless_get_task_by_index(enclave, task_index);
|
||||
uint32_t cur_status;
|
||||
@@ -178,8 +195,8 @@ cc_enclave_result_t uswitchless_get_task_result(cc_enclave_t *enclave, int task_
|
||||
while (true) {
|
||||
cur_status = __atomic_load_n(&task->status, __ATOMIC_ACQUIRE);
|
||||
if (cur_status == SL_TASK_DONE_SUCCESS) {
|
||||
- if ((retval != NULL) && (retval_size != 0)) {
|
||||
- (void)memcpy(retval, (void *)&task->ret_val, retval_size);
|
||||
+ if ((retval != NULL) && (task->retval_size > 0)) {
|
||||
+ (void)memcpy(retval, (void *)&task->ret_val, task->retval_size);
|
||||
}
|
||||
|
||||
return CC_SUCCESS;
|
||||
@@ -199,3 +216,22 @@ cc_enclave_result_t uswitchless_get_task_result(cc_enclave_t *enclave, int task_
|
||||
|
||||
return CC_ERROR_TIMEOUT;
|
||||
}
|
||||
+
|
||||
+cc_enclave_result_t uswitchless_get_async_task_result(cc_enclave_t *enclave, int task_index, void *retval)
|
||||
+{
|
||||
+ sl_task_t *task = uswitchless_get_task_by_index(enclave, task_index);
|
||||
+ uint32_t cur_status;
|
||||
+
|
||||
+ cur_status = __atomic_load_n(&task->status, __ATOMIC_ACQUIRE);
|
||||
+ if (cur_status == SL_TASK_DONE_SUCCESS) {
|
||||
+ if ((retval != NULL) && (task->retval_size > 0)) {
|
||||
+ (void)memcpy(retval, (void *)&task->ret_val, task->retval_size);
|
||||
+ }
|
||||
+
|
||||
+ return CC_SUCCESS;
|
||||
+ } else if (cur_status == SL_TASK_DONE_FAILED) {
|
||||
+ return (cc_enclave_result_t)task->ret_val;
|
||||
+ }
|
||||
+
|
||||
+ return CC_ERROR_SWITCHLESS_ASYNC_TASK_UNFINISHED;
|
||||
+}
|
||||
diff --git a/src/host_src/gp/gp_uswitchless.h b/src/host_src/gp/gp_uswitchless.h
|
||||
index 4d957ce..13ac14a 100644
|
||||
--- a/src/host_src/gp/gp_uswitchless.h
|
||||
+++ b/src/host_src/gp/gp_uswitchless.h
|
||||
@@ -81,18 +81,26 @@ void uswitchless_put_idle_task_by_index(cc_enclave_t *enclave, int task_index);
|
||||
void uswitchless_submit_task(cc_enclave_t *enclave, int task_index);
|
||||
|
||||
/*
|
||||
- * Summary: submitting a task
|
||||
+ * Summary: Obtains the result of the switchless invoking task
|
||||
* Parameters:
|
||||
* enclave: enclave
|
||||
* task_index: index of an task area
|
||||
* ret_val: address that accepts the return value
|
||||
- * ret_val_size: size of the return value
|
||||
* Return: CC_SUCCESS, success; others failed.
|
||||
*/
|
||||
-cc_enclave_result_t uswitchless_get_task_result(cc_enclave_t *enclave,
|
||||
- int task_index,
|
||||
- void *ret_val,
|
||||
- size_t ret_val_size);
|
||||
+cc_enclave_result_t uswitchless_get_task_result(cc_enclave_t *enclave, int task_index, void *ret_val);
|
||||
+
|
||||
+/*
|
||||
+ * Summary: Obtains the result of the switchless asynchronous invoking task
|
||||
+ * Parameters:
|
||||
+ * enclave: enclave
|
||||
+ * task_index: index of an task area
|
||||
+ * ret_val: address that accepts the return value
|
||||
+ * Return: CC_SUCCESS, success;
|
||||
+ CC_ERROR_SWITCHLESS_ASYNC_TASK_UNFINISHED, the asynchronous invoking task is not completed;
|
||||
+ others failed.
|
||||
+ */
|
||||
+cc_enclave_result_t uswitchless_get_async_task_result(cc_enclave_t *enclave, int task_index, void *retval);
|
||||
|
||||
/*
|
||||
* Summary: whether the switchless features is enabled
|
||||
@@ -115,17 +123,30 @@ bool uswitchless_is_switchless_enabled(cc_enclave_t *enclave);
|
||||
*/
|
||||
bool uswitchless_is_valid_param_num(cc_enclave_t *enclave, uint32_t argc);
|
||||
|
||||
+/*
|
||||
+ * Summary: whether the task index is valid
|
||||
+ * Parameters:
|
||||
+ * enclave: enclave
|
||||
+ * argc: task index
|
||||
+ * Return:
|
||||
+ * true: the task index is valid
|
||||
+ * false: invalid task index
|
||||
+ */
|
||||
+bool uswitchless_is_valid_task_index(cc_enclave_t *enclave, int task_index);
|
||||
+
|
||||
/*
|
||||
* Summary: fill a task
|
||||
* Parameters:
|
||||
* enclave: enclave
|
||||
* task_index: index of an task area
|
||||
* func_id: switchless function index
|
||||
+ * retval_size: size of the return value of the function
|
||||
* argc: number of parameters
|
||||
* args: parameter buffer
|
||||
* Return: NA
|
||||
*/
|
||||
-void uswitchless_fill_task(cc_enclave_t *enclave, int task_index, uint32_t func_id, uint32_t argc, const void *args);
|
||||
+void uswitchless_fill_task(cc_enclave_t *enclave, int task_index, uint16_t func_id, uint16_t retval_size,
|
||||
+ uint32_t argc, const void *args);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
diff --git a/tools/codegener/Genheader.ml b/tools/codegener/Genheader.ml
|
||||
index 9d0514c..e00157d 100644
|
||||
--- a/tools/codegener/Genheader.ml
|
||||
+++ b/tools/codegener/Genheader.ml
|
||||
@@ -71,6 +71,27 @@ let generate_rproxy_prototype (fd: func_decl) =
|
||||
"cc_enclave_result_t " ^ func_name ^ enclave_decl ^ func_args ^")";
|
||||
]
|
||||
|
||||
+let generate_rproxy_prototype_sl_async (tf: trusted_func) =
|
||||
+ if not tf.tf_is_switchless then
|
||||
+ [""]
|
||||
+ else
|
||||
+ let fd = tf.tf_fdecl in
|
||||
+ let func_name = fd.fname ^ "_async" in
|
||||
+ let enclave_decl = "(\n cc_enclave_t *enclave,\n int *task_id" in
|
||||
+ let func_args =
|
||||
+ let func_args_list =
|
||||
+ List.map (fun f -> gen_parm_str f) fd.plist
|
||||
+ in
|
||||
+ if List.length fd.plist > 0 then
|
||||
+ let func_args_pre = String.concat ",\n " func_args_list in
|
||||
+ ",\n " ^ func_args_pre
|
||||
+ else
|
||||
+ ""
|
||||
+ in
|
||||
+ [
|
||||
+ "cc_enclave_result_t " ^ func_name ^ enclave_decl ^ func_args ^")";
|
||||
+ ]
|
||||
+
|
||||
let generate_parm_str (p: pdecl) =
|
||||
let (_, declr) = p in
|
||||
declr.identifier
|
||||
@@ -344,14 +365,20 @@ let generate_untrusted_header (ec: enclave_content) =
|
||||
let r_proxy_proto =
|
||||
List.map (fun f -> generate_rproxy_prototype f.tf_fdecl) ec.tfunc_decls
|
||||
in
|
||||
+ let r_proxy_proto_sl_async =
|
||||
+ List.map (fun f -> generate_rproxy_prototype_sl_async f) ec.tfunc_decls
|
||||
+ in
|
||||
let r_proxy =
|
||||
String.concat ";\n\n" (List.flatten r_proxy_proto)
|
||||
in
|
||||
+ let r_proxy_sl_async =
|
||||
+ String.concat ";\n\n" (List.flatten r_proxy_proto_sl_async)
|
||||
+ in
|
||||
[
|
||||
hfile_start ^ hfile_include;
|
||||
c_start;
|
||||
agent_id;
|
||||
- trust_fproto_com ^ r_proxy ^ ";";
|
||||
+ trust_fproto_com ^ r_proxy ^ r_proxy_sl_async ^ ";";
|
||||
if (List.length ec.ufunc_decls <> 0) then untrust_fproto_com ^ untrust_func ^ ";"
|
||||
else "/**** There is no untrusted function ****/";
|
||||
c_end;
|
||||
diff --git a/tools/codegener/Genuntrust.ml b/tools/codegener/Genuntrust.ml
|
||||
index dc3010d..6fb4967 100644
|
||||
--- a/tools/codegener/Genuntrust.ml
|
||||
+++ b/tools/codegener/Genuntrust.ml
|
||||
@@ -98,6 +98,24 @@ let set_ecall_func_arguments (fd : func_decl) =
|
||||
else "")
|
||||
]
|
||||
|
||||
+let set_sl_async_ecall_func_arguments (fd : func_decl) =
|
||||
+ [
|
||||
+ sprintf "cc_enclave_result_t %s(\n %s" (fd.fname ^ "_async") "cc_enclave_t *enclave,\n int *task_id"
|
||||
+ ^ (if fd.plist <> [] then
|
||||
+ ",\n " ^
|
||||
+ concat ",\n "
|
||||
+ (List.map
|
||||
+ (fun (ptype, decl) ->
|
||||
+ match ptype with
|
||||
+ PTVal ty -> (sprintf "%s %s" (get_tystr ty) decl.identifier)
|
||||
+ | PTPtr (t, a) -> match (a.pa_rdonly, is_array decl) with
|
||||
+ | (true, false) -> sprintf "const %s %s" (get_tystr t) decl.identifier
|
||||
+ | (false, true) -> sprintf "%s %s%s" (get_tystr t) decl.identifier (set_array_dims_str decl.array_dims)
|
||||
+ | (_, _) -> sprintf "%s %s" (get_tystr t) decl.identifier)
|
||||
+ fd.plist)
|
||||
+ else "")
|
||||
+ ]
|
||||
+
|
||||
let set_sl_ecall_func (tf : trusted_func) =
|
||||
let tfd = tf.tf_fdecl in
|
||||
let init_point = set_init_pointer tfd in
|
||||
@@ -162,20 +180,52 @@ let set_sl_ecall_func (tf : trusted_func) =
|
||||
" /* Call the cc_enclave function */";
|
||||
|
||||
" sl_ecall_func_info_t func_info = {";
|
||||
- " .func_id = " ^ "fid_" ^ tfd.fname ^ ",";
|
||||
+ " .func_id = " ^ "fid_" ^ tfd.fname ^ ",\n .retval_size= " ^ out_retval_size ^ ",";
|
||||
" .argc = " ^ num_params ^ ",";
|
||||
" .args = " ^ out_params ^ ",";
|
||||
" };";
|
||||
|
||||
" ret = enclave->list_ops_node->ops_desc->ops->cc_sl_ecall_enclave(enclave,";
|
||||
" " ^ out_retval ^ ",";
|
||||
- " " ^ out_retval_size ^ ",";
|
||||
" &func_info);\n";
|
||||
|
||||
" pthread_rwlock_unlock(&enclave->rwlock);";
|
||||
(if tfd.plist <> [] then " free(params_buf);" else "");
|
||||
" return ret;";
|
||||
"}";
|
||||
+
|
||||
+ "";
|
||||
+ concat ",\n " (set_sl_async_ecall_func_arguments tfd) ^ ")";
|
||||
+ "{";
|
||||
+ " cc_enclave_result_t ret;\n";
|
||||
+ " if (enclave == NULL) {";
|
||||
+ " return CC_ERROR_BAD_PARAMETERS;";
|
||||
+ " }\n";
|
||||
+ " if (pthread_rwlock_rdlock(&enclave->rwlock)) {";
|
||||
+ " return CC_ERROR_BUSY;";
|
||||
+ " }\n";
|
||||
+ " if (enclave->list_ops_node == NULL ||\n enclave->list_ops_node->ops_desc == NULL ||";
|
||||
+ " enclave->list_ops_node->ops_desc->ops == NULL ||";
|
||||
+ " enclave->list_ops_node->ops_desc->ops->cc_sl_async_ecall == NULL) {";
|
||||
+ " pthread_rwlock_unlock(&enclave->rwlock);";
|
||||
+ " return CC_ERROR_BAD_PARAMETERS;";
|
||||
+ " }";
|
||||
+ "";
|
||||
+ params;
|
||||
+ " /* Call the cc_enclave function */";
|
||||
+
|
||||
+ " sl_ecall_func_info_t func_info = {";
|
||||
+ " .func_id = " ^ "fid_" ^ tfd.fname ^ ",\n .retval_size= " ^ out_retval_size ^ ",";
|
||||
+ " .argc = " ^ num_params ^ ",";
|
||||
+ " .args = " ^ out_params ^ ",";
|
||||
+ " };";
|
||||
+
|
||||
+ " ret = enclave->list_ops_node->ops_desc->ops->cc_sl_async_ecall(enclave, task_id, &func_info);\n";
|
||||
+
|
||||
+ " pthread_rwlock_unlock(&enclave->rwlock);";
|
||||
+ (if tfd.plist <> [] then " free(params_buf);" else "");
|
||||
+ " return ret;";
|
||||
+ "}";
|
||||
]
|
||||
|
||||
let set_ecall_func (tf : trusted_func) =
|
||||
--
|
||||
2.27.0
|
||||
|
||||
307
0052-rollback-to-common-invoking-when-async-invoking-fail.patch
Normal file
307
0052-rollback-to-common-invoking-when-async-invoking-fail.patch
Normal file
@ -0,0 +1,307 @@
|
||||
From 232ba565206caf01e7f514c0c5735a8e8d3ae06a Mon Sep 17 00:00:00 2001
|
||||
From: modric <wangyu283@huawei.com>
|
||||
Date: Wed, 9 Nov 2022 15:17:28 +0800
|
||||
Subject: [PATCH 3/4] rollback to common invoking when async invoking fails
|
||||
|
||||
---
|
||||
inc/host_inc/secgear_uswitchless.h | 7 ++-
|
||||
inc/host_inc/status.h | 1 +
|
||||
src/host_src/gp/gp_enclave.c | 5 ++
|
||||
src/host_src/gp/gp_uswitchless.c | 5 ++
|
||||
src/host_src/gp/gp_uswitchless.h | 10 ++++
|
||||
tools/codegener/Genheader.ml | 13 ++++-
|
||||
tools/codegener/Gentrust.ml | 10 ++--
|
||||
tools/codegener/Genuntrust.ml | 92 +++++++++++++++++++++++++++++-
|
||||
8 files changed, 133 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/inc/host_inc/secgear_uswitchless.h b/inc/host_inc/secgear_uswitchless.h
|
||||
index 8e21fd9..2ea4691 100644
|
||||
--- a/inc/host_inc/secgear_uswitchless.h
|
||||
+++ b/inc/host_inc/secgear_uswitchless.h
|
||||
@@ -81,10 +81,13 @@ typedef struct {
|
||||
uint32_t retries_before_sleep;
|
||||
|
||||
/* Worker thread scheduling policy, refer to cc_workers_policy_t, only for GP */
|
||||
- uint64_t workers_policy;
|
||||
+ uint32_t workers_policy;
|
||||
+
|
||||
+ /* Indicates whether to roll back to common invoking when asynchronous switchless invoking fails, only for GP */
|
||||
+ uint32_t rollback_to_common;
|
||||
} cc_sl_config_t;
|
||||
|
||||
-#define CC_USWITCHLESS_CONFIG_INITIALIZER {1, 1, 1, 16, 0, 0, WORKERS_POLICY_BUSY}
|
||||
+#define CC_USWITCHLESS_CONFIG_INITIALIZER {1, 1, 1, 16, 0, 0, WORKERS_POLICY_BUSY, 0}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
diff --git a/inc/host_inc/status.h b/inc/host_inc/status.h
|
||||
index 4f982f8..7f8daaa 100644
|
||||
--- a/inc/host_inc/status.h
|
||||
+++ b/inc/host_inc/status.h
|
||||
@@ -168,6 +168,7 @@ typedef enum _enclave_result_t
|
||||
CC_ERROR_ADDRESS_UNACCESSABLE, /* Memory address is not within enclave */
|
||||
CC_ERROR_SWITCHLESS_INVALID_TASK_ID, /* Invalid invoking task ID */
|
||||
CC_ERROR_SWITCHLESS_ASYNC_TASK_UNFINISHED, /* The asynchronous invoking task is not completed */
|
||||
+ CC_ERROR_SWITCHLESS_ROLLBACK2COMMON, /* rollback to common invoking when async invoking fails */
|
||||
CC_MAXIMUM_ERROR,
|
||||
} cc_enclave_result_t;
|
||||
|
||||
diff --git a/src/host_src/gp/gp_enclave.c b/src/host_src/gp/gp_enclave.c
|
||||
index 5345973..521a850 100644
|
||||
--- a/src/host_src/gp/gp_enclave.c
|
||||
+++ b/src/host_src/gp/gp_enclave.c
|
||||
@@ -857,6 +857,11 @@ cc_enclave_result_t cc_sl_async_ecall(cc_enclave_t *enclave, int *task_id, sl_ec
|
||||
|
||||
int task_index = uswitchless_get_idle_task_index(enclave);
|
||||
if (task_index < 0) {
|
||||
+ /* Need roll back to common invoking when asynchronous invoking fails. */
|
||||
+ if (uswitchless_need_rollback_to_common(enclave)) {
|
||||
+ return CC_ERROR_SWITCHLESS_ROLLBACK2COMMON;
|
||||
+ }
|
||||
+
|
||||
return CC_ERROR_SWITCHLESS_TASK_POOL_FULL;
|
||||
}
|
||||
|
||||
diff --git a/src/host_src/gp/gp_uswitchless.c b/src/host_src/gp/gp_uswitchless.c
|
||||
index 2a315ea..53ecc55 100644
|
||||
--- a/src/host_src/gp/gp_uswitchless.c
|
||||
+++ b/src/host_src/gp/gp_uswitchless.c
|
||||
@@ -112,6 +112,11 @@ bool uswitchless_is_valid_task_index(cc_enclave_t *enclave, int task_index)
|
||||
return !((*(pool->free_bit_buf + i)) & (1UL << j));
|
||||
}
|
||||
|
||||
+bool uswitchless_need_rollback_to_common(cc_enclave_t *enclave)
|
||||
+{
|
||||
+ return USWITCHLESS_TASK_POOL(enclave)->pool_cfg.rollback_to_common > 0;
|
||||
+}
|
||||
+
|
||||
int uswitchless_get_idle_task_index(cc_enclave_t *enclave)
|
||||
{
|
||||
sl_task_pool_t *pool = USWITCHLESS_TASK_POOL(enclave);
|
||||
diff --git a/src/host_src/gp/gp_uswitchless.h b/src/host_src/gp/gp_uswitchless.h
|
||||
index 13ac14a..a0ea117 100644
|
||||
--- a/src/host_src/gp/gp_uswitchless.h
|
||||
+++ b/src/host_src/gp/gp_uswitchless.h
|
||||
@@ -134,6 +134,16 @@ bool uswitchless_is_valid_param_num(cc_enclave_t *enclave, uint32_t argc);
|
||||
*/
|
||||
bool uswitchless_is_valid_task_index(cc_enclave_t *enclave, int task_index);
|
||||
|
||||
+/*
|
||||
+ * Summary: whether to roll back to common invoking when asynchronous switchless invoking fails
|
||||
+ * Parameters:
|
||||
+ * enclave: enclave
|
||||
+ * Return:
|
||||
+ * true: yes
|
||||
+ * false: no
|
||||
+ */
|
||||
+bool uswitchless_need_rollback_to_common(cc_enclave_t *enclave);
|
||||
+
|
||||
/*
|
||||
* Summary: fill a task
|
||||
* Parameters:
|
||||
diff --git a/tools/codegener/Genheader.ml b/tools/codegener/Genheader.ml
|
||||
index e00157d..0f244f3 100644
|
||||
--- a/tools/codegener/Genheader.ml
|
||||
+++ b/tools/codegener/Genheader.ml
|
||||
@@ -31,6 +31,14 @@ let generate_args_include (ufs: untrusted_func list) =
|
||||
"#include \"enclave.h\"\n" ^
|
||||
error_include ^ "\n"
|
||||
|
||||
+let generate_function_id_ex (tf: trusted_func) =
|
||||
+ let f = tf.tf_fdecl in
|
||||
+ let f_name = f.fname in
|
||||
+ if tf.tf_is_switchless then
|
||||
+ "fid_sl_async_" ^ f_name
|
||||
+ else
|
||||
+ "fid_" ^ f_name
|
||||
+
|
||||
let generate_function_id (f: func_decl) =
|
||||
let f_name = f.fname in
|
||||
"fid_" ^ f_name
|
||||
@@ -77,7 +85,8 @@ let generate_rproxy_prototype_sl_async (tf: trusted_func) =
|
||||
else
|
||||
let fd = tf.tf_fdecl in
|
||||
let func_name = fd.fname ^ "_async" in
|
||||
- let enclave_decl = "(\n cc_enclave_t *enclave,\n int *task_id" in
|
||||
+ let enclave_decl =
|
||||
+ "(\n " ^ (match fd.rtype with Void -> "cc_enclave_t *enclave,\n int *task_id" | _ -> "cc_enclave_t *enclave,\n int *task_id,\n " ^ (get_tystr fd.rtype ^ " *retval")) in
|
||||
let func_args =
|
||||
let func_args_list =
|
||||
List.map (fun f -> gen_parm_str f) fd.plist
|
||||
@@ -270,7 +279,7 @@ let generate_args_header (ec: enclave_content) =
|
||||
let trust_fid_body =
|
||||
let trust_fid_pre =
|
||||
List.mapi
|
||||
- (fun i f -> sprintf " %s = %d," (generate_function_id f.tf_fdecl) (i + 2)) tfunc_decls
|
||||
+ (fun i f -> sprintf " %s = %d," (generate_function_id_ex f) (i + 2)) ec.tfunc_decls
|
||||
in
|
||||
String.concat "\n" trust_fid_pre
|
||||
in
|
||||
diff --git a/tools/codegener/Gentrust.ml b/tools/codegener/Gentrust.ml
|
||||
index 6b6fa00..d950899 100644
|
||||
--- a/tools/codegener/Gentrust.ml
|
||||
+++ b/tools/codegener/Gentrust.ml
|
||||
@@ -146,6 +146,7 @@ let set_switchless_ecall_func (tf : trusted_func) =
|
||||
match tfd.rtype with
|
||||
| Void -> ""
|
||||
| _ -> " (void)memcpy(retval, &ret, sizeof(ret));" in
|
||||
+ if tf.tf_is_switchless then
|
||||
[
|
||||
sprintf "\nvoid sl_ecall_%s(void *task_buf)" tfd.fname;
|
||||
"{";
|
||||
@@ -160,15 +161,15 @@ let set_switchless_ecall_func (tf : trusted_func) =
|
||||
write_back_retval;
|
||||
"}";
|
||||
]
|
||||
+ else ["";]
|
||||
|
||||
let set_ecall_func (tf : trusted_func) =
|
||||
- if tf.tf_is_switchless then
|
||||
- set_switchless_ecall_func tf
|
||||
- else
|
||||
+ let slfunc = String.concat " " (set_switchless_ecall_func tf) in
|
||||
let tfd = tf.tf_fdecl in
|
||||
let params_point = set_parameters_point tfd in
|
||||
let out_params = set_out_params tfd in
|
||||
[
|
||||
+ "" ^ slfunc;
|
||||
sprintf "cc_enclave_result_t ecall_%s (" tfd.fname;
|
||||
" uint8_t* in_buf,";
|
||||
" size_t in_buf_size,";
|
||||
@@ -396,8 +397,7 @@ let gen_trusted(ec : enclave_content) =
|
||||
" (cc_ecall_func_t) ecall_unregister_shared_memory,";
|
||||
" " ^ concat ",\n "
|
||||
(List.map (fun (tf) ->
|
||||
- sprintf "(cc_ecall_func_t) ecall_%s" tf.tf_fdecl.fname)
|
||||
- (List.filter (fun tf -> not tf.tf_is_switchless) trust_funcs));
|
||||
+ sprintf "(cc_ecall_func_t) ecall_%s" tf.tf_fdecl.fname) trust_funcs);
|
||||
"};";
|
||||
"";
|
||||
"size_t ecall_table_size = CC_ARRAY_LEN(cc_ecall_tables);\n";
|
||||
diff --git a/tools/codegener/Genuntrust.ml b/tools/codegener/Genuntrust.ml
|
||||
index 6fb4967..8bc8e03 100644
|
||||
--- a/tools/codegener/Genuntrust.ml
|
||||
+++ b/tools/codegener/Genuntrust.ml
|
||||
@@ -80,6 +80,40 @@ let set_call_user_func (fd : func_decl) =
|
||||
"}";
|
||||
]
|
||||
|
||||
+let sl_async_set_call_user_func (fd : func_decl) =
|
||||
+ [
|
||||
+ "/* Call the cc_enclave function */";
|
||||
+ "if (!enclave) {";
|
||||
+ " ret = CC_ERROR_BAD_PARAMETERS;";
|
||||
+ " goto exit;";
|
||||
+ "}";
|
||||
+ "if (pthread_rwlock_rdlock(&enclave->rwlock)) {";
|
||||
+ " ret = CC_ERROR_BUSY;";
|
||||
+ " goto exit;";
|
||||
+ "}";
|
||||
+ "if (!enclave->list_ops_node || !enclave->list_ops_node->ops_desc ||";
|
||||
+ " !enclave->list_ops_node->ops_desc->ops ||";
|
||||
+ " !enclave->list_ops_node->ops_desc->ops->cc_ecall_enclave) {";
|
||||
+ " ret = CC_ERROR_BAD_PARAMETERS;";
|
||||
+ " goto exit;";
|
||||
+ "}";
|
||||
+ "if ((ret = enclave->list_ops_node->ops_desc->ops->cc_ecall_enclave(";
|
||||
+ " enclave,";
|
||||
+ sprintf " fid_sl_async_%s," fd.fname;
|
||||
+ " in_buf,";
|
||||
+ " in_buf_size,";
|
||||
+ " out_buf,";
|
||||
+ " out_buf_size,";
|
||||
+ " &ms,";
|
||||
+ " &ocall_table)) != CC_SUCCESS) {";
|
||||
+ " pthread_rwlock_unlock(&enclave->rwlock);";
|
||||
+ " goto exit; }";
|
||||
+ "if (pthread_rwlock_unlock(&enclave->rwlock)) {";
|
||||
+ " ret = CC_ERROR_BUSY;";
|
||||
+ " goto exit;";
|
||||
+ "}";
|
||||
+ ]
|
||||
+
|
||||
let set_ecall_func_arguments (fd : func_decl) =
|
||||
[
|
||||
sprintf "cc_enclave_result_t %s(\n %s" fd.fname (match fd.rtype with Void -> "cc_enclave_t *enclave" | _ -> "cc_enclave_t *enclave,\n " ^ (get_tystr fd.rtype ^ "* retval"))
|
||||
@@ -100,7 +134,7 @@ let set_ecall_func_arguments (fd : func_decl) =
|
||||
|
||||
let set_sl_async_ecall_func_arguments (fd : func_decl) =
|
||||
[
|
||||
- sprintf "cc_enclave_result_t %s(\n %s" (fd.fname ^ "_async") "cc_enclave_t *enclave,\n int *task_id"
|
||||
+ sprintf "cc_enclave_result_t %s(\n %s" (fd.fname ^ "_async") (match fd.rtype with Void -> "cc_enclave_t *enclave,\n int *task_id" | _ -> "cc_enclave_t *enclave,\n int *task_id,\n " ^ (get_tystr fd.rtype ^ " *retval"))
|
||||
^ (if fd.plist <> [] then
|
||||
",\n " ^
|
||||
concat ",\n "
|
||||
@@ -119,6 +153,7 @@ let set_sl_async_ecall_func_arguments (fd : func_decl) =
|
||||
let set_sl_ecall_func (tf : trusted_func) =
|
||||
let tfd = tf.tf_fdecl in
|
||||
let init_point = set_init_pointer tfd in
|
||||
+ let arg_size = set_args_size tfd in
|
||||
let get_param_name (_, decl) = decl.identifier in
|
||||
(*let is_ptr_type (ptype) =
|
||||
match ptype with
|
||||
@@ -224,6 +259,61 @@ let set_sl_ecall_func (tf : trusted_func) =
|
||||
|
||||
" pthread_rwlock_unlock(&enclave->rwlock);";
|
||||
(if tfd.plist <> [] then " free(params_buf);" else "");
|
||||
+ " if (ret != CC_ERROR_SWITCHLESS_ROLLBACK2COMMON) {\n return ret;\n }";
|
||||
+ "\n /* rollback to common invoking when async invoking fails */";
|
||||
+ " ret = CC_FAIL;";
|
||||
+ " *task_id = -1;";
|
||||
+ "";
|
||||
+ " /* Init buffer and size */";
|
||||
+ " size_t in_buf_size = 0;";
|
||||
+ " size_t out_buf_size = 0;";
|
||||
+ " uint8_t* in_buf = NULL;";
|
||||
+ " uint8_t* out_buf = NULL;";
|
||||
+ " uint32_t ms = TEE_SECE_AGENT_ID;";
|
||||
+ sprintf " %s_size_t args_size;" tfd.fname;
|
||||
+ "";
|
||||
+ " /* Init pointer */";
|
||||
+ if init_point <> ["";"";""] then
|
||||
+ concat "\n" init_point
|
||||
+ else " /* There is no pointer */";
|
||||
+ "";
|
||||
+ " memset(&args_size, 0, sizeof(args_size));";
|
||||
+ " /* Fill argments size */";
|
||||
+ if arg_size <> [""] then
|
||||
+ " " ^ concat "\n " (set_args_size tfd)
|
||||
+ else "/* There is no argments size */";
|
||||
+ "";
|
||||
+ sprintf " in_buf_size += size_to_aligned_size(sizeof(%s_size_t));"
|
||||
+ tfd.fname;
|
||||
+
|
||||
+ " " ^ concat "\n " (set_data_in tfd);
|
||||
+ "";
|
||||
+
|
||||
+ " " ^ concat "\n " (set_data_out tfd);
|
||||
+ "";
|
||||
+ " /* Allocate in_buf and out_buf */";
|
||||
+ " in_buf = (uint8_t*)malloc(in_buf_size);";
|
||||
+ " out_buf = (uint8_t*)malloc(out_buf_size);";
|
||||
+ " if (in_buf == NULL || out_buf == NULL) {";
|
||||
+ " ret = CC_ERROR_OUT_OF_MEMORY;";
|
||||
+ " goto exit;";
|
||||
+ " }";
|
||||
+
|
||||
+ "";
|
||||
+ " " ^ concat "\n " (set_in_memcpy tfd);
|
||||
+ "";
|
||||
+ " " ^ concat "\n " (sl_async_set_call_user_func tfd);
|
||||
+ "";
|
||||
+ " " ^ concat "\n " (set_out_memcpy tfd);
|
||||
+ " ret = CC_SUCCESS;";
|
||||
+ "";
|
||||
+
|
||||
+ "exit:";
|
||||
+ " if (in_buf)";
|
||||
+ " free(in_buf);";
|
||||
+ " if (out_buf)";
|
||||
+ " free(out_buf);";
|
||||
+ "";
|
||||
" return ret;";
|
||||
"}";
|
||||
]
|
||||
--
|
||||
2.27.0
|
||||
|
||||
860
0053-asynchronous-switchless-example.patch
Normal file
860
0053-asynchronous-switchless-example.patch
Normal file
@ -0,0 +1,860 @@
|
||||
From 508f9aed76b8f6788be60a8e39849ee6c1a32fcc Mon Sep 17 00:00:00 2001
|
||||
From: modric <wangyu283@huawei.com>
|
||||
Date: Wed, 9 Nov 2022 15:19:58 +0800
|
||||
Subject: [PATCH 4/4] asynchronous switchless example
|
||||
|
||||
---
|
||||
.../enclave/CMakeLists.txt | 16 +-
|
||||
.../switchless_performance/enclave/enclave.c | 77 ++
|
||||
examples/switchless_performance/host/main.c | 656 +++++++++++++++++-
|
||||
.../switchless_performance/switchless.edl | 13 +
|
||||
4 files changed, 750 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/examples/switchless_performance/enclave/CMakeLists.txt b/examples/switchless_performance/enclave/CMakeLists.txt
|
||||
index 69aab4c..f7b72b1 100644
|
||||
--- a/examples/switchless_performance/enclave/CMakeLists.txt
|
||||
+++ b/examples/switchless_performance/enclave/CMakeLists.txt
|
||||
@@ -62,7 +62,21 @@ set(COMMON_C_FLAGS "-W -Wall -Werror -fno-short-enums -fno-omit-frame-pointer -f
|
||||
set(COMMON_C_LINK_FLAGS "-Wl,-z,now -Wl,-z,relro -Wl,-z,noexecstack -Wl,-nostdlib -nodefaultlibs -nostartfiles")
|
||||
|
||||
if(CC_GP)
|
||||
- set(CMAKE_C_FLAGS "${COMMON_C_FLAGS} -march=armv8-a")
|
||||
+ if (CMAKE_COMPILER_IS_GNUCC)
|
||||
+ execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpfullversion -dumpversion
|
||||
+ OUTPUT_VARIABLE GCC_VERSION)
|
||||
+ string(REGEX MATCHALL "[0-9]+" GCC_VERSION_COMPONENTS ${GCC_VERSION})
|
||||
+ list(GET GCC_VERSION_COMPONENTS 0 GCC_MAJOR)
|
||||
+ list(GET GCC_VERSION_COMPONENTS 1 GCC_MINOR)
|
||||
+ set(GCC_VERSION "${GCC_MAJOR}.${GCC_MINOR}")
|
||||
+ endif()
|
||||
+
|
||||
+ if (GCC_VERSION GREATER_EQUAL "9.4")
|
||||
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a -mno-outline-atomics")
|
||||
+ else()
|
||||
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a")
|
||||
+ endif()
|
||||
+
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -s -fPIC")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${COMMON_C_LINK_FLAGS} -Wl,-s")
|
||||
|
||||
diff --git a/examples/switchless_performance/enclave/enclave.c b/examples/switchless_performance/enclave/enclave.c
|
||||
index 1320e53..8b1466f 100644
|
||||
--- a/examples/switchless_performance/enclave/enclave.c
|
||||
+++ b/examples/switchless_performance/enclave/enclave.c
|
||||
@@ -28,10 +28,87 @@ void test_toupper(char *buf, int len)
|
||||
}
|
||||
}
|
||||
|
||||
+static int i = 0;
|
||||
+static int j = 0;
|
||||
+
|
||||
void ecall_empty(void)
|
||||
{
|
||||
+ printf("normal %d\n", __atomic_add_fetch(&i, 1, __ATOMIC_ACQ_REL));
|
||||
+}
|
||||
+
|
||||
+int ecall_empty1(char *buf, int len)
|
||||
+{
|
||||
+ printf("normal1 %d\n", __atomic_add_fetch(&i, 1, __ATOMIC_ACQ_REL));
|
||||
+
|
||||
+ if (buf == NULL || len < 0) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ for (int i = 0; i < len; ++i) {
|
||||
+ if (buf[i] >= 'a' && buf[i] <= 'z') {
|
||||
+ buf[i] = buf[i] - ('a' - 'A');
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+int ecall_empty2(char *buf1, int len1, char *buf2, int len2)
|
||||
+{
|
||||
+ printf("normal2 %d\n", __atomic_add_fetch(&i, 1, __ATOMIC_ACQ_REL));
|
||||
+
|
||||
+ if (buf1 == NULL || len1 < 0 || buf2 == NULL || len2 < 0) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ for (int i = 0; i < len2; ++i) {
|
||||
+ if (buf1[i] >= 'a' && buf1[i] <= 'z') {
|
||||
+ buf2[i] = buf1[i] - ('a' - 'A');
|
||||
+ } else {
|
||||
+ buf2[i] = buf1[i];
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 2;
|
||||
}
|
||||
|
||||
void ecall_empty_switchless(void)
|
||||
{
|
||||
+ printf("sl %d\n", __atomic_add_fetch(&j, 1, __ATOMIC_ACQ_REL));
|
||||
+}
|
||||
+
|
||||
+int ecall_empty_switchless1(char *buf, int len)
|
||||
+{
|
||||
+ printf("sl1 %d\n", __atomic_add_fetch(&j, 1, __ATOMIC_ACQ_REL));
|
||||
+
|
||||
+ if (buf == NULL || len < 0) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ for (int i = 0; i < len; ++i) {
|
||||
+ if (buf[i] >= 'a' && buf[i] <= 'z') {
|
||||
+ buf[i] = buf[i] - ('a' - 'A');
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+int ecall_empty_switchless2(char *buf1, int len1, char *buf2, int len2)
|
||||
+{
|
||||
+ printf("sl2 %d\n", __atomic_add_fetch(&j, 1, __ATOMIC_ACQ_REL));
|
||||
+
|
||||
+ if (buf1 == NULL || len1 < 0 || buf2 == NULL || len2 < 0) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ for (int i = 0; i < len2; ++i) {
|
||||
+ if (buf1[i] >= 'a' && buf1[i] <= 'z') {
|
||||
+ buf2[i] = buf1[i] - ('a' - 'A');
|
||||
+ } else {
|
||||
+ buf2[i] = buf1[i];
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 2;
|
||||
}
|
||||
diff --git a/examples/switchless_performance/host/main.c b/examples/switchless_performance/host/main.c
|
||||
index f80db25..ea4994f 100644
|
||||
--- a/examples/switchless_performance/host/main.c
|
||||
+++ b/examples/switchless_performance/host/main.c
|
||||
@@ -63,23 +63,600 @@ void fini_enclave(cc_enclave_t *enclave)
|
||||
|
||||
void benchmark_ecall_empty(bool is_switchless, unsigned long nrepeats)
|
||||
{
|
||||
- struct timespec time_start;
|
||||
- struct timespec time_end;
|
||||
- struct timespec duration = {0, 0};
|
||||
+ struct timeval tval_before;
|
||||
+ struct timeval tval_after;
|
||||
+ struct timeval duration;
|
||||
cc_enclave_result_t(*ecall_fn)(cc_enclave_t *) = is_switchless ? ecall_empty_switchless : ecall_empty;
|
||||
|
||||
- clock_gettime(CLOCK_REALTIME, &time_start);
|
||||
+ gettimeofday(&tval_before, NULL);
|
||||
unsigned long tmp_nrepeats = nrepeats;
|
||||
while (tmp_nrepeats--) {
|
||||
ecall_fn(&g_enclave);
|
||||
}
|
||||
- clock_gettime(CLOCK_REALTIME, &time_end);
|
||||
|
||||
- duration.tv_sec += time_end.tv_sec - time_start.tv_sec;
|
||||
- duration.tv_nsec += time_end.tv_nsec - time_start.tv_nsec;
|
||||
+ gettimeofday(&tval_after, NULL);
|
||||
+ timersub(&tval_after, &tval_before, &duration);
|
||||
|
||||
- printf("Repeating an %s empty ecall for %lu times takes %lu.%09lus\n",
|
||||
- is_switchless ? "[switchless]" : "[ ordinary ]", nrepeats, duration.tv_sec, duration.tv_nsec);
|
||||
+ printf("Repeating an %s empty ecall for %lu times takes %ld.%06lds\n",
|
||||
+ is_switchless ? "[switchless]" : "[ ordinary ]", nrepeats, (long)duration.tv_sec, (long)duration.tv_usec);
|
||||
+}
|
||||
+
|
||||
+/* ecall_empty_switchless */
|
||||
+void benchmark_ecall_empty_sl_async(unsigned long nrepeats)
|
||||
+{
|
||||
+ cc_enclave_result_t ret_code;
|
||||
+ cc_enclave_result_t ret;
|
||||
+ struct timeval tval_before;
|
||||
+ struct timeval tval_after;
|
||||
+ struct timeval duration;
|
||||
+ int processed_cursor = 0;
|
||||
+ int retry_count = 0;
|
||||
+
|
||||
+ int *arr = (int *)calloc(nrepeats, sizeof(int));
|
||||
+ if (arr == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ // BEGIN
|
||||
+ gettimeofday(&tval_before, NULL);
|
||||
+
|
||||
+ for (int i = 0; i < nrepeats; ++i) {
|
||||
+ ret_code = ecall_empty_switchless_async(&g_enclave, &arr[i]);
|
||||
+ if (ret_code != CC_SUCCESS) {
|
||||
+ if (ret_code == CC_ERROR_SWITCHLESS_TASK_POOL_FULL) {
|
||||
+ // The task pool is full. You should try again later.
|
||||
+ --i;
|
||||
+ ++retry_count;
|
||||
+ } else {
|
||||
+ // Asynchronous invocation failed
|
||||
+ printf("Asynchronous invocation failed, ret=%x\n", ret_code);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = cc_sl_get_async_result(&g_enclave, arr[processed_cursor], NULL);
|
||||
+ if (ret == CC_ERROR_SWITCHLESS_ASYNC_TASK_UNFINISHED) {
|
||||
+ // Invoking processing
|
||||
+ } else if (ret == CC_SUCCESS) {
|
||||
+ // Obtaining the result succeeded
|
||||
+ processed_cursor++;
|
||||
+ } else {
|
||||
+ // Failed to obtain the result
|
||||
+ processed_cursor++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ while (processed_cursor < nrepeats) {
|
||||
+ ret = cc_sl_get_async_result(&g_enclave, arr[processed_cursor], NULL);
|
||||
+ if (ret == CC_ERROR_SWITCHLESS_ASYNC_TASK_UNFINISHED) {
|
||||
+ // Invoking processing
|
||||
+ continue;
|
||||
+ } else if (ret == CC_SUCCESS) {
|
||||
+ // Obtaining the result succeeded
|
||||
+ processed_cursor++;
|
||||
+ } else {
|
||||
+ // Failed to obtain the result
|
||||
+ processed_cursor++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // END
|
||||
+ gettimeofday(&tval_after, NULL);
|
||||
+ timersub(&tval_after, &tval_before, &duration);
|
||||
+
|
||||
+ free(arr);
|
||||
+
|
||||
+ printf("retry_count:%d, processed_cursor:%d\n", retry_count, processed_cursor);
|
||||
+ printf("Repeating an empty sl async ecall for %lu times takes %ld.%06lds\n", nrepeats,
|
||||
+ (long int)duration.tv_sec, (long int)duration.tv_usec);
|
||||
+}
|
||||
+
|
||||
+void benchmark_ecall_empty_sl_async_rollback(unsigned long nrepeats)
|
||||
+{
|
||||
+ cc_enclave_result_t ret_code;
|
||||
+ cc_enclave_result_t ret;
|
||||
+ struct timeval tval_before;
|
||||
+ struct timeval tval_after;
|
||||
+ struct timeval duration;
|
||||
+ int processed_cursor = 0;
|
||||
+ int rollback_count = 0;
|
||||
+ unsigned long tmp_nrepeats = nrepeats;
|
||||
+
|
||||
+ int *arr = (int *)calloc(nrepeats, sizeof(int));
|
||||
+ if (arr == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ // BEGIN
|
||||
+ gettimeofday(&tval_before, NULL);
|
||||
+
|
||||
+ for (int i = 0; i < tmp_nrepeats; ++i) {
|
||||
+ ret_code = ecall_empty_switchless_async(&g_enclave, &arr[i]);
|
||||
+ if (ret_code == CC_SUCCESS) {
|
||||
+ if (arr[i] == -1) {
|
||||
+ // rollback to common invoking when asynchronous switchless fails, and the common call is successful now
|
||||
+ --i;
|
||||
+ --tmp_nrepeats;
|
||||
+ rollback_count++;
|
||||
+ }
|
||||
+ } else {
|
||||
+ // Asynchronous invocation failed
|
||||
+ printf("Asynchronous invocation failed, ret=%x\n", ret_code);
|
||||
+ }
|
||||
+
|
||||
+ ret = cc_sl_get_async_result(&g_enclave, arr[processed_cursor], NULL);
|
||||
+ if (ret == CC_ERROR_SWITCHLESS_ASYNC_TASK_UNFINISHED) {
|
||||
+ // Invoking processing
|
||||
+ } else if (ret == CC_SUCCESS) {
|
||||
+ // Obtaining the result succeeded
|
||||
+ processed_cursor++;
|
||||
+ } else {
|
||||
+ // Failed to obtain the result
|
||||
+ processed_cursor++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ while (processed_cursor < tmp_nrepeats) {
|
||||
+ ret = cc_sl_get_async_result(&g_enclave, arr[processed_cursor], NULL);
|
||||
+ if (ret == CC_ERROR_SWITCHLESS_ASYNC_TASK_UNFINISHED) {
|
||||
+ // Invoking processing
|
||||
+ continue;
|
||||
+ } else if (ret == CC_SUCCESS) {
|
||||
+ // Obtaining the result succeeded
|
||||
+ processed_cursor++;
|
||||
+ } else {
|
||||
+ // Failed to obtain the result
|
||||
+ processed_cursor++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // END
|
||||
+ gettimeofday(&tval_after, NULL);
|
||||
+ timersub(&tval_after, &tval_before, &duration);
|
||||
+
|
||||
+ free(arr);
|
||||
+
|
||||
+ printf("rollback_count:%d, processed_cursor:%d\n", rollback_count, processed_cursor);
|
||||
+ printf("Repeating an empty sl async ecall rollback for %lu times takes %ld.%06lds\n", nrepeats,
|
||||
+ (long int)duration.tv_sec, (long int)duration.tv_usec);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/* ecall_empty_switchless1 */
|
||||
+void benchmark_ecall_empty_sl_async1(unsigned long nrepeats)
|
||||
+{
|
||||
+ cc_enclave_result_t ret_code;
|
||||
+ cc_enclave_result_t ret;
|
||||
+ struct timeval tval_before;
|
||||
+ struct timeval tval_after;
|
||||
+ struct timeval duration;
|
||||
+ int processed_cursor = 0;
|
||||
+ int retry_count = 0;
|
||||
+ int one_share_buf_len = 32;
|
||||
+ int retval;
|
||||
+
|
||||
+ int *arr = (int *)calloc(nrepeats, sizeof(int));
|
||||
+ if (arr == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ char *sharebuf = (char *)cc_malloc_shared_memory(&g_enclave, nrepeats * one_share_buf_len);
|
||||
+ if (sharebuf == NULL) {
|
||||
+ free(arr);
|
||||
+ printf("Error: malloc shared memory failed.\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ // BEGIN
|
||||
+ gettimeofday(&tval_before, NULL);
|
||||
+
|
||||
+ for (int i = 0; i < nrepeats; ++i) {
|
||||
+ strcpy(sharebuf + i * one_share_buf_len, "aAbBcCdD");
|
||||
+ ret_code = ecall_empty_switchless1_async(&g_enclave, &arr[i], NULL, sharebuf + i * one_share_buf_len,
|
||||
+ sizeof("aAbBcCdD"));
|
||||
+ if (ret_code != CC_SUCCESS) {
|
||||
+ if (ret_code == CC_ERROR_SWITCHLESS_TASK_POOL_FULL) {
|
||||
+ // The task pool is full. You should try again later.
|
||||
+ --i;
|
||||
+ ++retry_count;
|
||||
+ } else {
|
||||
+ // Asynchronous invocation failed
|
||||
+ printf("Asynchronous invocation failed, ret=%x\n", ret_code);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = cc_sl_get_async_result(&g_enclave, arr[processed_cursor], &retval);
|
||||
+ if (ret == CC_ERROR_SWITCHLESS_ASYNC_TASK_UNFINISHED) {
|
||||
+ // Invoking processing
|
||||
+ } else if (ret == CC_SUCCESS) {
|
||||
+ // Obtaining the result succeeded, and check the execution result.
|
||||
+ if (retval != 1) {
|
||||
+ printf("get result retval err:%d, index:%d\n", retval, processed_cursor);
|
||||
+ }
|
||||
+
|
||||
+ if (strcmp("AABBCCDD", sharebuf + processed_cursor * one_share_buf_len)) {
|
||||
+ printf("get result buffer err:%s, index:%d\n", sharebuf + processed_cursor * one_share_buf_len,
|
||||
+ processed_cursor);
|
||||
+ }
|
||||
+
|
||||
+ processed_cursor++;
|
||||
+ } else {
|
||||
+ // Failed to obtain the result
|
||||
+ processed_cursor++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ while (processed_cursor < nrepeats) {
|
||||
+ ret = cc_sl_get_async_result(&g_enclave, arr[processed_cursor], &retval);
|
||||
+ if (ret == CC_ERROR_SWITCHLESS_ASYNC_TASK_UNFINISHED) {
|
||||
+ // Invoking processing
|
||||
+ continue;
|
||||
+ } else if (ret == CC_SUCCESS) {
|
||||
+ // Obtaining the result succeeded, and check the execution result.
|
||||
+ if (retval != 1) {
|
||||
+ printf("get result retval err:%d, index:%d\n", retval, processed_cursor);
|
||||
+ }
|
||||
+
|
||||
+ if (strcmp("AABBCCDD", sharebuf + processed_cursor * one_share_buf_len)) {
|
||||
+ printf("get result buffer err:%s, index:%d\n", sharebuf + processed_cursor * one_share_buf_len,
|
||||
+ processed_cursor);
|
||||
+ }
|
||||
+
|
||||
+ processed_cursor++;
|
||||
+ } else {
|
||||
+ // Failed to obtain the result
|
||||
+ processed_cursor++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // END
|
||||
+ gettimeofday(&tval_after, NULL);
|
||||
+ timersub(&tval_after, &tval_before, &duration);
|
||||
+
|
||||
+ free(arr);
|
||||
+
|
||||
+ ret = cc_free_shared_memory(&g_enclave, sharebuf);
|
||||
+ if (ret != CC_SUCCESS) {
|
||||
+ printf("Error: free shared memory failed:%x.\n", ret);
|
||||
+ }
|
||||
+
|
||||
+ printf("retry_count:%d, processed_cursor:%d\n", retry_count, processed_cursor);
|
||||
+ printf("Repeating an empty sl async ecall [1] for %lu times takes %ld.%06lds\n", nrepeats,
|
||||
+ (long int)duration.tv_sec, (long int)duration.tv_usec);
|
||||
+}
|
||||
+
|
||||
+void benchmark_ecall_empty_sl_async_rollback1(unsigned long nrepeats)
|
||||
+{
|
||||
+ cc_enclave_result_t ret_code;
|
||||
+ cc_enclave_result_t ret;
|
||||
+ struct timeval tval_before;
|
||||
+ struct timeval tval_after;
|
||||
+ struct timeval duration;
|
||||
+ int processed_cursor = 0;
|
||||
+ int one_share_buf_len = 32;
|
||||
+ int rollback_count = 0;
|
||||
+ int retval;
|
||||
+ unsigned long tmp_nrepeats = nrepeats;
|
||||
+
|
||||
+ int *arr = (int *)calloc(nrepeats, sizeof(int));
|
||||
+ if (arr == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ char *sharebuf = (char *)cc_malloc_shared_memory(&g_enclave, nrepeats * one_share_buf_len);
|
||||
+ if (sharebuf == NULL) {
|
||||
+ free(arr);
|
||||
+ printf("Error: malloc shared memory failed.\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ // BEGIN
|
||||
+ gettimeofday(&tval_before, NULL);
|
||||
+
|
||||
+ for (int i = 0; i < tmp_nrepeats; ++i) {
|
||||
+ strcpy(sharebuf + i * one_share_buf_len, "aAbBcCdD");
|
||||
+ ret_code = ecall_empty_switchless1_async(&g_enclave, &arr[i], &retval, sharebuf + i * one_share_buf_len,
|
||||
+ sizeof("aAbBcCdD"));
|
||||
+ if (ret_code == CC_SUCCESS) {
|
||||
+ if (arr[i] == -1) {
|
||||
+ /*
|
||||
+ * rollback to common invoking when asynchronous switchless fails, and the common call
|
||||
+ * is successful now, check the execution result.
|
||||
+ */
|
||||
+ if (retval != 1) {
|
||||
+ printf("get result retval err:%d, index:%d\n", retval, i);
|
||||
+ }
|
||||
+
|
||||
+ if (strcmp("AABBCCDD", sharebuf + i * one_share_buf_len)) {
|
||||
+ printf("get result buffer err:%s, index:%d\n", sharebuf + i * one_share_buf_len, i);
|
||||
+ }
|
||||
+
|
||||
+ --i;
|
||||
+ --tmp_nrepeats;
|
||||
+ rollback_count++;
|
||||
+ }
|
||||
+ } else {
|
||||
+ // Asynchronous invocation failed
|
||||
+ printf("Asynchronous invocation failed, ret=%x\n", ret_code);
|
||||
+ }
|
||||
+
|
||||
+ ret = cc_sl_get_async_result(&g_enclave, arr[processed_cursor], &retval);
|
||||
+ if (ret == CC_ERROR_SWITCHLESS_ASYNC_TASK_UNFINISHED) {
|
||||
+ // Invoking processing
|
||||
+ } else if (ret == CC_SUCCESS) {
|
||||
+ // Obtaining the result succeeded, check the execution result.
|
||||
+ if (retval != 1) {
|
||||
+ printf("get result retval err:%d, index:%d\n", retval, processed_cursor);
|
||||
+ }
|
||||
+
|
||||
+ if (strcmp("AABBCCDD", sharebuf + processed_cursor * one_share_buf_len)) {
|
||||
+ printf("get result buffer err:%s, index:%d\n", sharebuf + processed_cursor * one_share_buf_len,
|
||||
+ processed_cursor);
|
||||
+ }
|
||||
+
|
||||
+ processed_cursor++;
|
||||
+ } else {
|
||||
+ // Failed to obtain the result
|
||||
+ processed_cursor++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ while (processed_cursor < tmp_nrepeats) {
|
||||
+ ret = cc_sl_get_async_result(&g_enclave, arr[processed_cursor], &retval);
|
||||
+ if (ret == CC_ERROR_SWITCHLESS_ASYNC_TASK_UNFINISHED) {
|
||||
+ // Invoking processing
|
||||
+ continue;
|
||||
+ } else if (ret == CC_SUCCESS) {
|
||||
+ // Obtaining the result succeeded, check the execution result.
|
||||
+ if (retval != 1) {
|
||||
+ printf("get result retval err:%d, index:%d\n", retval, processed_cursor);
|
||||
+ }
|
||||
+
|
||||
+ if (strcmp("AABBCCDD", sharebuf + processed_cursor * one_share_buf_len)) {
|
||||
+ printf("get result buffer err:%s, index:%d\n", sharebuf + processed_cursor * one_share_buf_len,
|
||||
+ processed_cursor);
|
||||
+ }
|
||||
+
|
||||
+ processed_cursor++;
|
||||
+ } else {
|
||||
+ // Failed to obtain the result
|
||||
+ processed_cursor++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // END
|
||||
+ gettimeofday(&tval_after, NULL);
|
||||
+ timersub(&tval_after, &tval_before, &duration);
|
||||
+
|
||||
+ free(arr);
|
||||
+ ret = cc_free_shared_memory(&g_enclave, sharebuf);
|
||||
+ if (ret != CC_SUCCESS) {
|
||||
+ printf("Error: free shared memory failed:%x.\n", ret);
|
||||
+ }
|
||||
+
|
||||
+ printf("rollback_count:%d, processed_cursor:%d\n", rollback_count, processed_cursor);
|
||||
+ printf("Repeating an empty sl async ecall rollback [1] for %lu times takes %ld.%06lds\n", nrepeats,
|
||||
+ (long int)duration.tv_sec, (long int)duration.tv_usec);
|
||||
+}
|
||||
+
|
||||
+/* ecall_empty_switchless2 */
|
||||
+void benchmark_ecall_empty_sl_async2(unsigned long nrepeats)
|
||||
+{
|
||||
+ cc_enclave_result_t ret_code;
|
||||
+ cc_enclave_result_t ret;
|
||||
+ struct timeval tval_before;
|
||||
+ struct timeval tval_after;
|
||||
+ struct timeval duration;
|
||||
+ int processed_cursor = 0;
|
||||
+ int retry_count = 0;
|
||||
+ int one_share_buf_len = 32;
|
||||
+ int half_one_share_buf_len = 16;
|
||||
+ int retval;
|
||||
+
|
||||
+ int *arr = (int *)calloc(nrepeats, sizeof(int));
|
||||
+ if (arr == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ char *sharebuf = (char *)cc_malloc_shared_memory(&g_enclave, nrepeats * one_share_buf_len);
|
||||
+ if (sharebuf == NULL) {
|
||||
+ free(arr);
|
||||
+ printf("Error: malloc shared memory failed.\n");
|
||||
+ return;
|
||||
+ }
|
||||
+ memset(sharebuf, 0, nrepeats * one_share_buf_len);
|
||||
+
|
||||
+ // BEGIN
|
||||
+ gettimeofday(&tval_before, NULL);
|
||||
+
|
||||
+ for (int i = 0; i < nrepeats; ++i) {
|
||||
+ strcpy(sharebuf + i * one_share_buf_len, "aAbBcCdD");
|
||||
+ ret_code = ecall_empty_switchless2_async(&g_enclave, &arr[i], NULL, sharebuf + i * one_share_buf_len,
|
||||
+ sizeof("aAbBcCdD"), sharebuf + i * one_share_buf_len + half_one_share_buf_len, sizeof("aAbBcCdD"));
|
||||
+ if (ret_code != CC_SUCCESS) {
|
||||
+ if (ret_code == CC_ERROR_SWITCHLESS_TASK_POOL_FULL) {
|
||||
+ // The task pool is full. You should try again later.
|
||||
+ --i;
|
||||
+ ++retry_count;
|
||||
+ } else {
|
||||
+ // Asynchronous invocation failed
|
||||
+ printf("Asynchronous invocation failed, ret=%x\n", ret_code);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = cc_sl_get_async_result(&g_enclave, arr[processed_cursor], &retval);
|
||||
+ if (ret == CC_ERROR_SWITCHLESS_ASYNC_TASK_UNFINISHED) {
|
||||
+ // Invoking processing
|
||||
+ } else if (ret == CC_SUCCESS) {
|
||||
+ // Obtaining the result succeeded, check the execution result.
|
||||
+ if (retval != 2) {
|
||||
+ printf("get result retval err:%d, index:%d\n", retval, processed_cursor);
|
||||
+ }
|
||||
+
|
||||
+ if (strcmp("AABBCCDD", sharebuf + processed_cursor * one_share_buf_len + half_one_share_buf_len)) {
|
||||
+ printf("get result buffer err:%s, index:%d\n",
|
||||
+ sharebuf + processed_cursor * one_share_buf_len + half_one_share_buf_len, processed_cursor);
|
||||
+ }
|
||||
+
|
||||
+ processed_cursor++;
|
||||
+ } else {
|
||||
+ // Failed to obtain the result
|
||||
+ processed_cursor++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ while (processed_cursor < nrepeats) {
|
||||
+ ret = cc_sl_get_async_result(&g_enclave, arr[processed_cursor], &retval);
|
||||
+ if (ret == CC_ERROR_SWITCHLESS_ASYNC_TASK_UNFINISHED) {
|
||||
+ // Invoking processing
|
||||
+ continue;
|
||||
+ } else if (ret == CC_SUCCESS) {
|
||||
+ // Obtaining the result succeeded, check the execution result.
|
||||
+ if (retval != 2) {
|
||||
+ printf("get result retval err:%d, index:%d\n", retval, processed_cursor);
|
||||
+ }
|
||||
+
|
||||
+ if (strcmp("AABBCCDD", sharebuf + processed_cursor * one_share_buf_len + half_one_share_buf_len)) {
|
||||
+ printf("get result buffer err:%s, index:%d\n",
|
||||
+ sharebuf + processed_cursor * one_share_buf_len + half_one_share_buf_len, processed_cursor);
|
||||
+ }
|
||||
+
|
||||
+ processed_cursor++;
|
||||
+ } else {
|
||||
+ // Failed to obtain the result
|
||||
+ processed_cursor++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // END
|
||||
+ gettimeofday(&tval_after, NULL);
|
||||
+ timersub(&tval_after, &tval_before, &duration);
|
||||
+
|
||||
+ free(arr);
|
||||
+
|
||||
+ ret = cc_free_shared_memory(&g_enclave, sharebuf);
|
||||
+ if (ret != CC_SUCCESS) {
|
||||
+ printf("Error: free shared memory failed:%x.\n", ret);
|
||||
+ }
|
||||
+
|
||||
+ printf("retry_count:%d, processed_cursor:%d\n", retry_count, processed_cursor);
|
||||
+ printf("Repeating an empty sl async ecall [2] for %lu times takes %ld.%06lds\n", nrepeats,
|
||||
+ (long int)duration.tv_sec, (long int)duration.tv_usec);
|
||||
+}
|
||||
+
|
||||
+void benchmark_ecall_empty_sl_async_rollback2(unsigned long nrepeats)
|
||||
+{
|
||||
+ cc_enclave_result_t ret_code;
|
||||
+ cc_enclave_result_t ret;
|
||||
+ struct timeval tval_before;
|
||||
+ struct timeval tval_after;
|
||||
+ struct timeval duration;
|
||||
+ int processed_cursor = 0;
|
||||
+ int one_share_buf_len = 32;
|
||||
+ int half_one_share_buf_len = 16;
|
||||
+ int rollback_count = 0;
|
||||
+ int retval;
|
||||
+ unsigned long tmp_nrepeats = nrepeats;
|
||||
+
|
||||
+ int *arr = (int *)calloc(nrepeats, sizeof(int));
|
||||
+ if (arr == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ char *sharebuf = (char *)cc_malloc_shared_memory(&g_enclave, nrepeats * one_share_buf_len);
|
||||
+ if (sharebuf == NULL) {
|
||||
+ free(arr);
|
||||
+ printf("Error: malloc shared memory failed.\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ // BEGIN
|
||||
+ gettimeofday(&tval_before, NULL);
|
||||
+
|
||||
+ for (int i = 0; i < tmp_nrepeats; ++i) {
|
||||
+ strcpy(sharebuf + i * one_share_buf_len, "aAbBcCdD");
|
||||
+ ret_code = ecall_empty_switchless2_async(&g_enclave, &arr[i], &retval, sharebuf + i * one_share_buf_len,
|
||||
+ sizeof("aAbBcCdD"), sharebuf + i * one_share_buf_len + half_one_share_buf_len, sizeof("aAbBcCdD"));
|
||||
+ if (ret_code == CC_SUCCESS) {
|
||||
+ if (arr[i] == -1) {
|
||||
+ /*
|
||||
+ * rollback to common invoking when asynchronous switchless fails, and the common call
|
||||
+ * is successful now, check the execution result.
|
||||
+ */
|
||||
+ if (retval != 2) {
|
||||
+ printf("get result retval err:%d, index:%d\n", retval, i);
|
||||
+ }
|
||||
+
|
||||
+ if (strcmp("AABBCCDD", sharebuf + i * one_share_buf_len + half_one_share_buf_len)) {
|
||||
+ printf("get result buffer err:%s, index:%d\n",
|
||||
+ sharebuf + i * one_share_buf_len + half_one_share_buf_len, i);
|
||||
+ }
|
||||
+
|
||||
+ --i;
|
||||
+ --tmp_nrepeats;
|
||||
+ rollback_count++;
|
||||
+ }
|
||||
+ } else {
|
||||
+ // Asynchronous invocation failed
|
||||
+ printf("Asynchronous invocation failed, ret=%x\n", ret_code);
|
||||
+ }
|
||||
+
|
||||
+ ret = cc_sl_get_async_result(&g_enclave, arr[processed_cursor], &retval);
|
||||
+ if (ret == CC_ERROR_SWITCHLESS_ASYNC_TASK_UNFINISHED) {
|
||||
+ // Invoking processing
|
||||
+ } else if (ret == CC_SUCCESS) {
|
||||
+ // Obtaining the result succeeded, check the execution result.
|
||||
+ if (retval != 2) {
|
||||
+ printf("get result retval err:%d, index:%d\n", retval, processed_cursor);
|
||||
+ }
|
||||
+
|
||||
+ if (strcmp("AABBCCDD", sharebuf + processed_cursor * one_share_buf_len + half_one_share_buf_len)) {
|
||||
+ printf("get result buffer err:%s, index:%d\n",
|
||||
+ sharebuf + processed_cursor * one_share_buf_len + half_one_share_buf_len, processed_cursor);
|
||||
+ }
|
||||
+
|
||||
+ processed_cursor++;
|
||||
+ } else {
|
||||
+ // Failed to obtain the result
|
||||
+ processed_cursor++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ while (processed_cursor < tmp_nrepeats) {
|
||||
+ ret = cc_sl_get_async_result(&g_enclave, arr[processed_cursor], &retval);
|
||||
+ if (ret == CC_ERROR_SWITCHLESS_ASYNC_TASK_UNFINISHED) {
|
||||
+ // Invoking processing
|
||||
+ continue;
|
||||
+ } else if (ret == CC_SUCCESS) {
|
||||
+ // Obtaining the result succeeded, check the execution result.
|
||||
+ if (retval != 2) {
|
||||
+ printf("get result retval err:%d, index:%d\n", retval, processed_cursor);
|
||||
+ }
|
||||
+
|
||||
+ if (strcmp("AABBCCDD", sharebuf + processed_cursor * one_share_buf_len + half_one_share_buf_len)) {
|
||||
+ printf("get result buffer err:%s, index:%d\n",
|
||||
+ sharebuf + processed_cursor * one_share_buf_len + half_one_share_buf_len, processed_cursor);
|
||||
+ }
|
||||
+
|
||||
+ processed_cursor++;
|
||||
+ } else {
|
||||
+ // Failed to obtain the result
|
||||
+ processed_cursor++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // END
|
||||
+ gettimeofday(&tval_after, NULL);
|
||||
+ timersub(&tval_after, &tval_before, &duration);
|
||||
+
|
||||
+ free(arr);
|
||||
+ ret = cc_free_shared_memory(&g_enclave, sharebuf);
|
||||
+ if (ret != CC_SUCCESS) {
|
||||
+ printf("Error: free shared memory failed:%x.\n", ret);
|
||||
+ }
|
||||
+
|
||||
+ printf("rollback_count:%d, processed_cursor:%d\n", rollback_count, processed_cursor);
|
||||
+ printf("Repeating an empty sl async ecall rollback [2] for %lu times takes %ld.%06lds\n", nrepeats,
|
||||
+ (long int)duration.tv_sec, (long int)duration.tv_usec);
|
||||
}
|
||||
|
||||
#define TEST_STR "switchless"
|
||||
@@ -106,11 +683,35 @@ void transfer_data_using_shared_memory()
|
||||
}
|
||||
}
|
||||
|
||||
+void onetime_normal(void)
|
||||
+{
|
||||
+ cc_enclave_result_t ret;
|
||||
+ int retval;
|
||||
+
|
||||
+ char buf[] = "aAbBcCdD";
|
||||
+ ret = ecall_empty1(&g_enclave, &retval, buf, sizeof(buf));
|
||||
+ if (ret != CC_SUCCESS) {
|
||||
+ printf("Error: ecall_empty1, ret:%x.\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+ printf("buf:%s, retval:%d\n", buf, retval);
|
||||
+
|
||||
+ char buf1[] = "aAbBcCdD";
|
||||
+ char buf2[32] = {0};
|
||||
+ ret = ecall_empty2(&g_enclave, &retval, buf1, sizeof(buf1), buf2, sizeof(buf1) - 3);
|
||||
+ if (ret != CC_SUCCESS) {
|
||||
+ printf("Error: ecall_empty2, ret:%x.\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+ printf("buf2:%s, retval:%d\n", buf2, retval);
|
||||
+}
|
||||
+
|
||||
int main(void)
|
||||
{
|
||||
cc_sl_config_t sl_cfg = CC_USWITCHLESS_CONFIG_INITIALIZER;
|
||||
sl_cfg.num_tworkers = 2; /* 2 tworkers */
|
||||
- sl_cfg.sl_call_pool_size_qwords = 2; /* 2 * 64 tasks */
|
||||
+ sl_cfg.sl_call_pool_size_qwords = 8; /* 2 * 64 tasks */
|
||||
+ sl_cfg.rollback_to_common = false;
|
||||
enclave_features_t features = {ENCLAVE_FEATURE_SWITCHLESS, (void *)&sl_cfg};
|
||||
|
||||
if (!init_enclave(&features)) {
|
||||
@@ -119,14 +720,47 @@ int main(void)
|
||||
}
|
||||
|
||||
printf("\n1. Running a benchmark that compares [ordinary] and [switchless] ecall\n");
|
||||
- unsigned long nrepeats = 100000;
|
||||
+ unsigned long nrepeats = 10000;
|
||||
+ benchmark_ecall_empty(false, nrepeats);
|
||||
+ benchmark_ecall_empty(true, nrepeats);
|
||||
+
|
||||
+ benchmark_ecall_empty_sl_async(nrepeats);
|
||||
+ benchmark_ecall_empty_sl_async1(nrepeats);
|
||||
+ benchmark_ecall_empty_sl_async2(nrepeats);
|
||||
+
|
||||
+ printf("\n2. Transfer data using shared memory\n");
|
||||
+ transfer_data_using_shared_memory();
|
||||
+
|
||||
+ printf("\n3. normal ecall\n");
|
||||
+ onetime_normal();
|
||||
+
|
||||
+ fini_enclave(&g_enclave);
|
||||
+
|
||||
+#if 1
|
||||
+ printf("\n=================================================\n");
|
||||
+
|
||||
+ sl_cfg.rollback_to_common = true;
|
||||
+ if (!init_enclave(&features)) {
|
||||
+ printf("Error: init enclave failed\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ printf("\n1. Running a benchmark that compares [ordinary] and [switchless] ecall\n");
|
||||
benchmark_ecall_empty(false, nrepeats);
|
||||
benchmark_ecall_empty(true, nrepeats);
|
||||
|
||||
+ benchmark_ecall_empty_sl_async_rollback(nrepeats);
|
||||
+ benchmark_ecall_empty_sl_async_rollback1(nrepeats);
|
||||
+ benchmark_ecall_empty_sl_async_rollback2(nrepeats);
|
||||
+
|
||||
printf("\n2. Transfer data using shared memory\n");
|
||||
transfer_data_using_shared_memory();
|
||||
|
||||
+ printf("\n3. normal ecall\n");
|
||||
+ onetime_normal();
|
||||
+
|
||||
fini_enclave(&g_enclave);
|
||||
+#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
diff --git a/examples/switchless_performance/switchless.edl b/examples/switchless_performance/switchless.edl
|
||||
index 344ee57..3c6f32e 100644
|
||||
--- a/examples/switchless_performance/switchless.edl
|
||||
+++ b/examples/switchless_performance/switchless.edl
|
||||
@@ -16,8 +16,21 @@ enclave {
|
||||
from "secgear_tswitchless.edl" import *;
|
||||
trusted {
|
||||
public void ecall_empty(void);
|
||||
+
|
||||
+ /* test [in, out] params */
|
||||
+ public int ecall_empty1([in, out, size=len]char *buf, int len);
|
||||
+
|
||||
+ /* test [in] and [out] params */
|
||||
+ public int ecall_empty2([in, size=len1]char *buf1, int len1, [out, size=len2]char *buf2, int len2);
|
||||
+
|
||||
public void ecall_empty_switchless(void) transition_using_threads;
|
||||
|
||||
+ /* test [in, out] params */
|
||||
+ public int ecall_empty_switchless1([in, out, size=len]char *buf, int len) transition_using_threads;
|
||||
+
|
||||
+ /* test [in] and [out] params */
|
||||
+ public int ecall_empty_switchless2([in, size=len1]char *buf1, int len1, [out, size=len2]char *buf2, int len2) transition_using_threads;
|
||||
+
|
||||
public void test_toupper([in, out, size=len]char *buf, int len) transition_using_threads;
|
||||
};
|
||||
};
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
Name: secGear
|
||||
Version: 0.1.0
|
||||
Release: 27
|
||||
Release: 28
|
||||
Summary: secGear is an SDK to develop confidential computing apps based on hardware enclave features
|
||||
|
||||
|
||||
@ -58,6 +58,10 @@ Patch45: 0046-fix-return-value.patch
|
||||
Patch46: 0047-del-print-uncontrol-form-string.patch
|
||||
Patch47: 0048-Delete-the-null-determination-of-out_buf-in-codegene.patch
|
||||
Patch48: 0049-support-switchless-feature.patch
|
||||
Patch49: 0050-switchless-schedule-policy.patch
|
||||
Patch50: 0051-asynchronous-switchless.patch
|
||||
Patch51: 0052-rollback-to-common-invoking-when-async-invoking-fail.patch
|
||||
Patch52: 0053-asynchronous-switchless-example.patch
|
||||
|
||||
BuildRequires: gcc python automake autoconf libtool
|
||||
BUildRequires: glibc glibc-devel cmake ocaml-dune rpm gcc-c++
|
||||
@ -176,6 +180,9 @@ popd
|
||||
systemctl restart rsyslog
|
||||
|
||||
%changelog
|
||||
* Thu Nov 10 2022 wangyu <wangyu283@huawei.com> - 0.1.0-28
|
||||
- DESC: support switchless scheduling plicies and asynchronous calls
|
||||
|
||||
* Tue Oct 18 2022 zhengxiaoxiao <zhengxiaoxiao2@huawei.com> - 0.1.0-27
|
||||
- DESC: support switchless feature
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user