This gave a significant performance improvement.
yagl_api_func (*get_func)(struct yagl_api_ps */*api_ps*/,
uint32_t /*func_id*/);
- void (*bad_call)(void);
-
void (*thread_fini)(struct yagl_api_ps */*api_ps*/);
void (*fini)(struct yagl_api_ps */*api_ps*/);
return true;
}
-static void yagl_host_egl_bad_call(void)
-{
- YAGL_LOG_FUNC_SET_TS(egl_api_ts->ts, yagl_host_egl_bad_call);
- YAGL_SET_ERR(EGL_BAD_PARAMETER);
-}
-
static yagl_api_func yagl_host_egl_get_func(struct yagl_api_ps *api_ps,
uint32_t func_id)
{
egl_api_ps->base.thread_init = &yagl_host_egl_thread_init;
egl_api_ps->base.get_func = &yagl_host_egl_get_func;
- egl_api_ps->base.bad_call = &yagl_host_egl_bad_call;
egl_api_ps->base.thread_fini = &yagl_host_egl_thread_fini;
egl_api_ps->base.fini = &yagl_host_egl_process_fini;
egl_api_ps->base.destroy = &yagl_host_egl_process_destroy;
return &ctx->base.base;
}
-static void yagl_host_gles2_bad_call(void)
-{
-}
-
static yagl_api_func yagl_host_gles2_get_func(struct yagl_api_ps *api_ps,
uint32_t func_id)
{
gles2_api_ps->base.thread_init = &yagl_host_gles2_thread_init;
gles2_api_ps->base.get_func = &yagl_host_gles2_get_func;
- gles2_api_ps->base.bad_call = &yagl_host_gles2_bad_call;
gles2_api_ps->base.thread_fini = &yagl_host_gles2_thread_fini;
gles2_api_ps->base.fini = &yagl_host_gles2_process_fini;
gles2_api_ps->base.destroy = &yagl_host_gles2_process_destroy;
#define YAGL_MEM_SIZE 0x1000
-#define YAGL_BUFF_SIZE 0x1000
-
#define YAGL_MAX_USERS (YAGL_MEM_SIZE / YAGL_REGS_SIZE)
struct yagl_user
{
target_phys_addr_t buff_len = YAGL_BUFF_SIZE;
uint8_t *buff = NULL;
- uint8_t *current_buff;
YAGL_LOG_FUNC_ENTER_NPT(yagl_device_trigger, "%d", user_index);
goto out;
}
- current_buff = buff;
-
- while (true) {
- uint8_t *tmp;
-
- if (current_buff >= (buff + YAGL_BUFF_SIZE)) {
- YAGL_LOG_CRITICAL("batch passes the end of buffer, protocol error");
-
- memset(s->in_buff, 0, YAGL_MARSHAL_MAX_RESPONSE);
-
- break;
- }
-
- current_buff = yagl_server_dispatch(s->ss,
- s->users[user_index].process_id,
- s->users[user_index].thread_id,
- current_buff,
- s->in_buff);
-
- if (!current_buff) {
- /*
- * Error occured.
- */
-
- break;
- }
-
- tmp = current_buff;
-
- /*
- * Take a peak to see if there's a batch terminator.
- */
-
- if (!yagl_marshal_get_uint32(&tmp)) {
- break;
- }
- }
+ yagl_server_dispatch(s->ss,
+ s->users[user_index].process_id,
+ s->users[user_index].thread_id,
+ buff,
+ s->in_buff);
memcpy(buff, s->in_buff, YAGL_MARSHAL_MAX_RESPONSE);
*/
#define YAGL_MARSHAL_MAX_RESPONSE (8 * 2)
+/*
+ * Max batch buffer size.
+ */
+#define YAGL_BUFF_SIZE 0x1000
+
static __inline int yagl_marshal_skip(uint8_t** buff)
{
*buff += 8;
}
}
-/*
- * out_buff is:
- * (yagl_api_id) api_id
- * (yagl_func_id) func_id
- * ... api_id/func_id dependent
- * in_buff must be:
- * (uint32_t) 1/0 - call ok/failed
- * ... api_id/func_id dependent
- */
-uint8_t *yagl_server_dispatch(struct yagl_server_state *ss,
- yagl_pid target_pid,
- yagl_tid target_tid,
- uint8_t *out_buff,
- uint8_t *in_buff)
+void yagl_server_dispatch(struct yagl_server_state *ss,
+ yagl_pid target_pid,
+ yagl_tid target_tid,
+ uint8_t *out_buff,
+ uint8_t *in_buff)
{
- yagl_api_id api_id = yagl_marshal_get_api_id(&out_buff);
- yagl_func_id func_id = yagl_marshal_get_func_id(&out_buff);
- struct yagl_api* api;
struct yagl_thread_state *ts;
- uint8_t *in_buff_ret;
YAGL_LOG_FUNC_ENTER(target_pid,
target_tid,
yagl_server_dispatch,
- "api_id = %u, func_id = %u",
- api_id,
- func_id);
+ NULL);
ts = yagl_server_find_thread(ss, target_pid, target_tid);
- if (!ts) {
+ if (ts) {
+ yagl_thread_call(ts, out_buff, in_buff);
+ } else {
YAGL_LOG_CRITICAL(
"process/thread %u/%u not found",
target_pid, target_tid);
yagl_marshal_put_uint32(&in_buff, 0);
-
- YAGL_LOG_FUNC_EXIT(NULL);
-
- return NULL;
}
- if ((api_id <= 0) || (api_id > YAGL_NUM_APIS)) {
- YAGL_LOG_CRITICAL(
- "target-host protocol error, bad api_id - %u", api_id);
-
- yagl_marshal_put_uint32(&in_buff, 0);
-
- YAGL_LOG_FUNC_EXIT(NULL);
-
- return NULL;
- }
-
- api = ss->apis[api_id - 1];
-
- if (!api) {
- YAGL_LOG_CRITICAL(
- "uninitialized api - %u. host logic error", api_id);
-
- yagl_marshal_put_uint32(&in_buff, 0);
-
- YAGL_LOG_FUNC_EXIT(NULL);
-
- return NULL;
- }
-
- in_buff_ret = in_buff;
-
- yagl_marshal_skip(&in_buff);
-
- out_buff = yagl_thread_call(ts, api_id, func_id, out_buff, in_buff);
-
- yagl_marshal_put_uint32(&in_buff_ret, (out_buff ? 1 : 0));
-
YAGL_LOG_FUNC_EXIT(NULL);
-
- return out_buff;
}
void yagl_server_dispatch_exit(struct yagl_server_state *ss,
uint8_t *in_buff);
/*
- * This is called for each host YaGL call. Returns new
- * position of 'out_buff' on success and NULL on failure.
+ * This is called for each YaGL batch.
*/
-uint8_t *yagl_server_dispatch(struct yagl_server_state *ss,
- yagl_pid target_pid,
- yagl_tid target_tid,
- uint8_t *out_buff,
- uint8_t *in_buff);
+void yagl_server_dispatch(struct yagl_server_state *ss,
+ yagl_pid target_pid,
+ yagl_tid target_tid,
+ uint8_t *out_buff,
+ uint8_t *in_buff);
/*
* This is called for last YaGL call.
}
while (true) {
- struct yagl_api_ps *api_ps;
- yagl_api_func func;
+ bool ret = true;
+ uint8_t *current_buff;
+ uint8_t *tmp;
yagl_event_wait(&ts->call_event);
break;
}
- YAGL_LOG_TRACE("calling (api = %u, func = %u)",
- ts->current_api,
- ts->current_func);
+ current_buff = ts->current_out_buff;
- api_ps = ts->ps->api_states[ts->current_api - 1];
- assert(api_ps);
+ /*
+ * current_buff is:
+ * (yagl_api_id) api_id
+ * (yagl_func_id) func_id
+ * ... api_id/func_id dependent
+ * current_in_buff must be:
+ * (uint32_t) 1/0 - call ok/failed
+ * ... api_id/func_id dependent
+ */
- func = api_ps->get_func(api_ps, ts->current_func);
+ while (true) {
+ yagl_api_id api_id;
+ yagl_func_id func_id;
+ struct yagl_api_ps *api_ps;
+ yagl_api_func func;
- if (!func) {
- api_ps->bad_call();
- ts->current_out_buff = NULL;
- } else {
- ts->current_out_buff = func(ts,
- ts->current_out_buff,
- ts->current_in_buff);
+ if (current_buff >= (ts->current_out_buff + YAGL_BUFF_SIZE)) {
+ YAGL_LOG_CRITICAL("batch passes the end of buffer, protocol error");
+
+ ret = false;
+
+ break;
+ }
+
+ api_id = yagl_marshal_get_api_id(¤t_buff);
+
+ if (api_id == 0) {
+ /*
+ * Batch ended.
+ */
+
+ break;
+ }
+
+ func_id = yagl_marshal_get_func_id(¤t_buff);
+
+ YAGL_LOG_TRACE("calling (api = %u, func = %u)",
+ api_id,
+ func_id);
+
+ if ((api_id <= 0) || (api_id > YAGL_NUM_APIS)) {
+ YAGL_LOG_CRITICAL("target-host protocol error, bad api_id - %u", api_id);
+
+ ret = false;
+
+ break;
+ }
+
+ api_ps = ts->ps->api_states[api_id - 1];
+
+ if (!api_ps) {
+ YAGL_LOG_CRITICAL("uninitialized api - %u. host logic error", api_id);
+
+ ret = false;
+
+ break;
+ }
+
+ func = api_ps->get_func(api_ps, func_id);
+
+ if (func) {
+ tmp = ts->current_in_buff;
+
+ yagl_marshal_skip(&tmp);
+
+ current_buff = func(ts,
+ current_buff,
+ tmp);
+ } else {
+ YAGL_LOG_CRITICAL("bad function call (api = %u, func = %u)",
+ api_id,
+ func_id);
+
+ ret = false;
+
+ break;
+ }
}
+ tmp = ts->current_in_buff;
+
+ yagl_marshal_put_uint32(&tmp, (ret ? 1 : 0));
+
yagl_event_set(&ts->call_processed_event);
}
g_free(ts);
}
-uint8_t *yagl_thread_call(struct yagl_thread_state *ts,
- yagl_api_id api_id,
- yagl_func_id func_id,
- uint8_t *out_buff,
- uint8_t *in_buff)
+void yagl_thread_call(struct yagl_thread_state *ts,
+ uint8_t *out_buff,
+ uint8_t *in_buff)
{
- YAGL_LOG_FUNC_ENTER_TS(ts,
- yagl_thread_call,
- "api = %u, func = %u",
- api_id,
- func_id);
+ YAGL_LOG_FUNC_ENTER_TS(ts, yagl_thread_call, NULL);
assert(cpu_single_env);
- ts->current_api = api_id;
- ts->current_func = func_id;
ts->current_out_buff = out_buff;
ts->current_in_buff = in_buff;
ts->current_env = cpu_single_env;
- YAGL_LOG_TRACE("calling (api = %u, func = %u)",
- ts->current_api,
- ts->current_func);
-
yagl_cpu_synchronize_state(ts->ps);
yagl_event_set(&ts->call_event);
yagl_event_wait(&ts->call_processed_event);
YAGL_LOG_FUNC_EXIT(NULL);
-
- return ts->current_out_buff;
}
* @}
*/
- volatile yagl_api_id current_api;
-
- volatile yagl_func_id current_func;
-
/*
* Allocated by the caller of yagl_thread_call,
* invalidated after function return.
void yagl_thread_state_destroy(struct yagl_thread_state *ts);
-/*
- * Returns new position of 'out_buff' on success and NULL on failure.
- */
-uint8_t *yagl_thread_call(struct yagl_thread_state *ts,
- yagl_api_id api_id,
- yagl_func_id func_id,
- uint8_t *out_buff,
- uint8_t *in_buff);
+void yagl_thread_call(struct yagl_thread_state *ts,
+ uint8_t *out_buff,
+ uint8_t *in_buff);
#define YAGL_BARRIER_ARG(ts)
#define YAGL_BARRIER_RET(ts) 1