libgomp-plugin-intelmic.cpp (OFFLOAD_ACTIVE_WAIT_ENV): New define.
liboffloadmic/ * plugin/libgomp-plugin-intelmic.cpp (OFFLOAD_ACTIVE_WAIT_ENV): New define. (init): Set OFFLOAD_ACTIVE_WAIT env var to 0, if it is not set. * runtime/emulator/coi_common.h (PIPE_HOST_PATH): Replace with ... (PIPE_HOST2TGT_NAME): ... this. (PIPE_TARGET_PATH): Replace with ... (PIPE_TGT2HOST_NAME): ... this. (MALLOCN): New define. (READN): Likewise. (WRITEN): Likewise. (enum cmd_t): Replace CMD_RUN_FUNCTION with CMD_PIPELINE_RUN_FUNCTION. Add CMD_PIPELINE_CREATE, CMD_PIPELINE_DESTROY. * runtime/emulator/coi_device.cpp (engine_dir): New static variable. (pipeline_thread_routine): New static function. (COIProcessWaitForShutdown): Use global engine_dir instead of mic_dir. Rename pipe_host and pipe_target to pipe_host2tgt and pipe_tgt2host. If cmd is CMD_PIPELINE_CREATE, create a new thread for the pipeline. Remove cmd == CMD_RUN_FUNCTION case. * runtime/emulator/coi_device.h (COIERRORN): New define. * runtime/emulator/coi_host.cpp: Include set, map, queue. Replace typedefs with enums and structs. (struct Function): Remove name, add num_buffers, bufs_size, bufs_data_target, misc_data_len, misc_data, return_value_len, return_value, completion_event. (struct Callback): New. (struct Process): Remove pipeline. Add pipe_host2tgt and pipe_tgt2host. (struct Pipeline): Remove pipe_host and pipe_target. Add thread, destroy, is_destroyed, pipe_host2tgt_path, pipe_tgt2host_path, pipe_host2tgt, pipe_tgt2host, queue, process. (max_pipeline_num): New static variable. (pipelines): Likewise. (max_event_num): Likewise. (non_signalled_events): Likewise. (errored_events): Likewise. (callbacks): Likewise. (cleanup): Do not check tmp_dirs before free. (start_critical_section): New static function. (finish_critical_section): Likewise. (pipeline_is_destroyed): Likewise. (maybe_invoke_callback): Likewise. (signal_event): Likewise. (get_event_result): Likewise. (COIBufferCopy): Rename arguments according to headers. Add asserts. Use process' main pipes, instead of pipeline's pipes. Signal completion event. (COIBufferCreate): Rename arguments according to headers. Add asserts. Use process' main pipes, instead of pipeline's pipes. (COIBufferCreateFromMemory): Rename arguments according to headers. Add asserts. (COIBufferDestroy): Rename arguments according to headers. Add asserts. Use process' main pipes, instead of pipeline's pipes. (COIBufferGetSinkAddress): Rename arguments according to headers. Add asserts. (COIBufferMap): Rename arguments according to headers. Add asserts. Signal completion event. (COIBufferRead): Likewise. (COIBufferSetState): Likewise. (COIBufferUnmap): Likewise. (COIBufferWrite): Likewise. (COIEngineGetCount): Add assert. (COIEngineGetHandle): Rename arguments according to headers. Add assert. (COIEventWait): Rename arguments according to headers. Add asserts. Implement waiting for events with zero or infinite timeout. (COIEventRegisterCallback): New function. (pipeline_thread_routine): New static function. (COIPipelineCreate): Create a new thread for the pipeline. (COIPipelineDestroy): Exit pipeline thread. (COIPipelineRunFunction): Add the function into pipeline's queue, instead running it here. Wait for it's completion in case of synchronous execution. (COIProcessCreateFromMemory): Rename arguments according to headers. Add asserts. Create process' main pipes, instead of pipeline's pipes. (COIProcessDestroy): Rename arguments according to headers. Add asserts. Destroy all undestroyed pipelines. (COIProcessGetFunctionHandles): Rename arguments according to headers. Add asserts. Use process' main pipes, instead of pipeline's pipes. Remove useless function names. (COIProcessLoadLibraryFromMemory): Add asserts. Use process' main pipes, instead of pipeline's pipes. (COIProcessUnloadLibrary): Likewise. (COIEngineGetInfo): Add assert. * runtime/emulator/coi_host.h (COIERRORN): New define. From-SVN: r228248
This commit is contained in:
parent
b59882293f
commit
44799f87c3
7 changed files with 1121 additions and 606 deletions
|
@ -1,3 +1,89 @@
|
|||
2015-09-29 Ilya Verbin <ilya.verbin@intel.com>
|
||||
|
||||
* plugin/libgomp-plugin-intelmic.cpp (OFFLOAD_ACTIVE_WAIT_ENV): New
|
||||
define.
|
||||
(init): Set OFFLOAD_ACTIVE_WAIT env var to 0, if it is not set.
|
||||
* runtime/emulator/coi_common.h (PIPE_HOST_PATH): Replace with ...
|
||||
(PIPE_HOST2TGT_NAME): ... this.
|
||||
(PIPE_TARGET_PATH): Replace with ...
|
||||
(PIPE_TGT2HOST_NAME): ... this.
|
||||
(MALLOCN): New define.
|
||||
(READN): Likewise.
|
||||
(WRITEN): Likewise.
|
||||
(enum cmd_t): Replace CMD_RUN_FUNCTION with CMD_PIPELINE_RUN_FUNCTION.
|
||||
Add CMD_PIPELINE_CREATE, CMD_PIPELINE_DESTROY.
|
||||
* runtime/emulator/coi_device.cpp (engine_dir): New static variable.
|
||||
(pipeline_thread_routine): New static function.
|
||||
(COIProcessWaitForShutdown): Use global engine_dir instead of mic_dir.
|
||||
Rename pipe_host and pipe_target to pipe_host2tgt and pipe_tgt2host.
|
||||
If cmd is CMD_PIPELINE_CREATE, create a new thread for the pipeline.
|
||||
Remove cmd == CMD_RUN_FUNCTION case.
|
||||
* runtime/emulator/coi_device.h (COIERRORN): New define.
|
||||
* runtime/emulator/coi_host.cpp: Include set, map, queue.
|
||||
Replace typedefs with enums and structs.
|
||||
(struct Function): Remove name, add num_buffers, bufs_size,
|
||||
bufs_data_target, misc_data_len, misc_data, return_value_len,
|
||||
return_value, completion_event.
|
||||
(struct Callback): New.
|
||||
(struct Process): Remove pipeline. Add pipe_host2tgt and pipe_tgt2host.
|
||||
(struct Pipeline): Remove pipe_host and pipe_target. Add thread,
|
||||
destroy, is_destroyed, pipe_host2tgt_path, pipe_tgt2host_path,
|
||||
pipe_host2tgt, pipe_tgt2host, queue, process.
|
||||
(max_pipeline_num): New static variable.
|
||||
(pipelines): Likewise.
|
||||
(max_event_num): Likewise.
|
||||
(non_signalled_events): Likewise.
|
||||
(errored_events): Likewise.
|
||||
(callbacks): Likewise.
|
||||
(cleanup): Do not check tmp_dirs before free.
|
||||
(start_critical_section): New static function.
|
||||
(finish_critical_section): Likewise.
|
||||
(pipeline_is_destroyed): Likewise.
|
||||
(maybe_invoke_callback): Likewise.
|
||||
(signal_event): Likewise.
|
||||
(get_event_result): Likewise.
|
||||
(COIBufferCopy): Rename arguments according to headers. Add asserts.
|
||||
Use process' main pipes, instead of pipeline's pipes. Signal completion
|
||||
event.
|
||||
(COIBufferCreate): Rename arguments according to headers. Add asserts.
|
||||
Use process' main pipes, instead of pipeline's pipes.
|
||||
(COIBufferCreateFromMemory): Rename arguments according to headers.
|
||||
Add asserts.
|
||||
(COIBufferDestroy): Rename arguments according to headers. Add asserts.
|
||||
Use process' main pipes, instead of pipeline's pipes.
|
||||
(COIBufferGetSinkAddress): Rename arguments according to headers.
|
||||
Add asserts.
|
||||
(COIBufferMap): Rename arguments according to headers. Add asserts.
|
||||
Signal completion event.
|
||||
(COIBufferRead): Likewise.
|
||||
(COIBufferSetState): Likewise.
|
||||
(COIBufferUnmap): Likewise.
|
||||
(COIBufferWrite): Likewise.
|
||||
(COIEngineGetCount): Add assert.
|
||||
(COIEngineGetHandle): Rename arguments according to headers.
|
||||
Add assert.
|
||||
(COIEventWait): Rename arguments according to headers. Add asserts.
|
||||
Implement waiting for events with zero or infinite timeout.
|
||||
(COIEventRegisterCallback): New function.
|
||||
(pipeline_thread_routine): New static function.
|
||||
(COIPipelineCreate): Create a new thread for the pipeline.
|
||||
(COIPipelineDestroy): Exit pipeline thread.
|
||||
(COIPipelineRunFunction): Add the function into pipeline's queue,
|
||||
instead running it here. Wait for it's completion in case of
|
||||
synchronous execution.
|
||||
(COIProcessCreateFromMemory): Rename arguments according to headers.
|
||||
Add asserts. Create process' main pipes, instead of pipeline's pipes.
|
||||
(COIProcessDestroy): Rename arguments according to headers.
|
||||
Add asserts. Destroy all undestroyed pipelines.
|
||||
(COIProcessGetFunctionHandles): Rename arguments according to headers.
|
||||
Add asserts. Use process' main pipes, instead of pipeline's pipes.
|
||||
Remove useless function names.
|
||||
(COIProcessLoadLibraryFromMemory): Add asserts. Use process' main
|
||||
pipes, instead of pipeline's pipes.
|
||||
(COIProcessUnloadLibrary): Likewise.
|
||||
(COIEngineGetInfo): Add assert.
|
||||
* runtime/emulator/coi_host.h (COIERRORN): New define.
|
||||
|
||||
2015-09-28 Ilya Verbin <ilya.verbin@intel.com>
|
||||
|
||||
PR other/67652
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
#define LD_LIBRARY_PATH_ENV "LD_LIBRARY_PATH"
|
||||
#define MIC_LD_LIBRARY_PATH_ENV "MIC_LD_LIBRARY_PATH"
|
||||
#define OFFLOAD_ACTIVE_WAIT_ENV "OFFLOAD_ACTIVE_WAIT"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define TRACE(...) \
|
||||
|
@ -115,18 +116,23 @@ static VarDesc vd_tgt2host = {
|
|||
};
|
||||
|
||||
|
||||
/* Add path specified in LD_LIBRARY_PATH to MIC_LD_LIBRARY_PATH, which is
|
||||
required by liboffloadmic. */
|
||||
__attribute__((constructor))
|
||||
static void
|
||||
init (void)
|
||||
{
|
||||
const char *ld_lib_path = getenv (LD_LIBRARY_PATH_ENV);
|
||||
const char *mic_lib_path = getenv (MIC_LD_LIBRARY_PATH_ENV);
|
||||
const char *active_wait = getenv (OFFLOAD_ACTIVE_WAIT_ENV);
|
||||
|
||||
/* Disable active wait by default to avoid useless CPU usage. */
|
||||
if (!active_wait)
|
||||
setenv (OFFLOAD_ACTIVE_WAIT_ENV, "0", 0);
|
||||
|
||||
if (!ld_lib_path)
|
||||
goto out;
|
||||
|
||||
/* Add path specified in LD_LIBRARY_PATH to MIC_LD_LIBRARY_PATH, which is
|
||||
required by liboffloadmic. */
|
||||
if (!mic_lib_path)
|
||||
setenv (MIC_LD_LIBRARY_PATH_ENV, ld_lib_path, 1);
|
||||
else
|
||||
|
|
|
@ -72,11 +72,11 @@
|
|||
/* Relative path to directory with pipes. */
|
||||
#define PIPES_PATH "/pipes"
|
||||
|
||||
/* Relative path to target-to-host pipe. */
|
||||
#define PIPE_HOST_PATH PIPES_PATH"/host"
|
||||
/* Non-numerical part of host-to-target pipe file name. */
|
||||
#define PIPE_HOST2TGT_NAME PIPES_PATH "/host2tgt_"
|
||||
|
||||
/* Relative path to host-to-target pipe. */
|
||||
#define PIPE_TARGET_PATH PIPES_PATH"/target"
|
||||
/* Non-numerical part of target-to-host pipe file name. */
|
||||
#define PIPE_TGT2HOST_NAME PIPES_PATH "/tgt2host_"
|
||||
|
||||
/* Non-numerical part of shared memory file name. */
|
||||
#define SHM_NAME "/offload_shm_"
|
||||
|
@ -99,6 +99,15 @@
|
|||
ptr = p; \
|
||||
}
|
||||
|
||||
/* Like MALLOC, but return NULL instead of COIRESULT. */
|
||||
#define MALLOCN(type, ptr, size) \
|
||||
{ \
|
||||
type p = (type) malloc (size); \
|
||||
if (p == NULL) \
|
||||
COIERRORN ("Cannot allocate memory."); \
|
||||
ptr = p; \
|
||||
}
|
||||
|
||||
/* Wrapper for strdup. */
|
||||
#define STRDUP(ptr, str) \
|
||||
{ \
|
||||
|
@ -116,6 +125,14 @@
|
|||
COIERROR ("Cannot read from pipe."); \
|
||||
}
|
||||
|
||||
/* Like READ, but return NULL instead of COIRESULT. */
|
||||
#define READN(pipe, ptr, size) \
|
||||
{ \
|
||||
int s = (int) size; \
|
||||
if (read (pipe, ptr, s) != s) \
|
||||
COIERRORN ("Cannot read from pipe."); \
|
||||
}
|
||||
|
||||
/* Wrapper for pipe writing. */
|
||||
#define WRITE(pipe, ptr, size) \
|
||||
{ \
|
||||
|
@ -124,6 +141,14 @@
|
|||
COIERROR ("Cannot write in pipe."); \
|
||||
}
|
||||
|
||||
/* Like WRITE, but return NULL instead of COIRESULT. */
|
||||
#define WRITEN(pipe, ptr, size) \
|
||||
{ \
|
||||
int s = (int) size; \
|
||||
if (write (pipe, ptr, s) != s) \
|
||||
COIERRORN ("Cannot write in pipe."); \
|
||||
}
|
||||
|
||||
|
||||
/* Command codes enum. */
|
||||
typedef enum
|
||||
|
@ -134,7 +159,9 @@ typedef enum
|
|||
CMD_GET_FUNCTION_HANDLE,
|
||||
CMD_OPEN_LIBRARY,
|
||||
CMD_CLOSE_LIBRARY,
|
||||
CMD_RUN_FUNCTION,
|
||||
CMD_PIPELINE_CREATE,
|
||||
CMD_PIPELINE_DESTROY,
|
||||
CMD_PIPELINE_RUN_FUNCTION,
|
||||
CMD_SHUTDOWN
|
||||
} cmd_t;
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
|
||||
static uint32_t engine_index;
|
||||
static char *engine_dir;
|
||||
|
||||
|
||||
extern "C"
|
||||
|
@ -68,7 +69,7 @@ SYMBOL_VERSION (COIEngineGetIndex, 1) (COI_ISA_TYPE *type,
|
|||
{
|
||||
COITRACE ("COIEngineGetIndex");
|
||||
|
||||
/* type is not used in liboffload. */
|
||||
/* type is not used in liboffloadmic. */
|
||||
*index = engine_index;
|
||||
|
||||
return COI_SUCCESS;
|
||||
|
@ -86,50 +87,144 @@ SYMBOL_VERSION (COIPipelineStartExecutingRunFunctions, 1) ()
|
|||
}
|
||||
|
||||
|
||||
/* The start routine for the COI pipeline thread. */
|
||||
|
||||
static void *
|
||||
pipeline_thread_routine (void *in_pipeline_num)
|
||||
{
|
||||
uint32_t pipeline_num = *(uint32_t *) in_pipeline_num;
|
||||
free (in_pipeline_num);
|
||||
|
||||
/* Open pipes. */
|
||||
char *pipe_host2tgt_path, *pipe_tgt2host_path;
|
||||
MALLOCN (char *, pipe_host2tgt_path,
|
||||
strlen (engine_dir) + sizeof (PIPE_HOST2TGT_NAME "0000000000"));
|
||||
MALLOCN (char *, pipe_tgt2host_path,
|
||||
strlen (engine_dir) + sizeof (PIPE_TGT2HOST_NAME "0000000000"));
|
||||
sprintf (pipe_host2tgt_path, "%s" PIPE_HOST2TGT_NAME "%010d", engine_dir,
|
||||
pipeline_num);
|
||||
sprintf (pipe_tgt2host_path, "%s" PIPE_TGT2HOST_NAME "%010d", engine_dir,
|
||||
pipeline_num);
|
||||
int pipe_host2tgt = open (pipe_host2tgt_path, O_CLOEXEC | O_RDONLY);
|
||||
if (pipe_host2tgt < 0)
|
||||
COIERRORN ("Cannot open host-to-target pipe.");
|
||||
int pipe_tgt2host = open (pipe_tgt2host_path, O_CLOEXEC | O_WRONLY);
|
||||
if (pipe_tgt2host < 0)
|
||||
COIERRORN ("Cannot open target-to-host pipe.");
|
||||
|
||||
free (pipe_host2tgt_path);
|
||||
free (pipe_tgt2host_path);
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* Read and execute command. */
|
||||
cmd_t cmd = CMD_PIPELINE_DESTROY;
|
||||
int cmd_len = read (pipe_host2tgt, &cmd, sizeof (cmd_t));
|
||||
if (cmd_len != sizeof (cmd_t) && cmd_len != 0)
|
||||
COIERRORN ("Cannot read from pipe.");
|
||||
|
||||
if (cmd == CMD_PIPELINE_DESTROY)
|
||||
break;
|
||||
else if (cmd == CMD_PIPELINE_RUN_FUNCTION)
|
||||
{
|
||||
/* Receive data from host. */
|
||||
void (*func) (uint32_t, void **, uint64_t *, void *, uint16_t, void *,
|
||||
uint16_t);
|
||||
uint32_t buffer_count;
|
||||
READN (pipe_host2tgt, &func, sizeof (void *));
|
||||
READN (pipe_host2tgt, &buffer_count, sizeof (uint32_t));
|
||||
void **buffers;
|
||||
uint64_t *buffers_len;
|
||||
MALLOCN (void **, buffers, buffer_count * sizeof (void *));
|
||||
MALLOCN (uint64_t *, buffers_len, buffer_count * sizeof (uint64_t));
|
||||
for (uint32_t i = 0; i < buffer_count; i++)
|
||||
{
|
||||
READN (pipe_host2tgt, &buffers_len[i], sizeof (uint64_t));
|
||||
READN (pipe_host2tgt, &buffers[i], sizeof (void *));
|
||||
}
|
||||
uint16_t misc_data_len;
|
||||
READN (pipe_host2tgt, &misc_data_len, sizeof (uint16_t));
|
||||
void *misc_data = NULL;
|
||||
if (misc_data_len > 0)
|
||||
{
|
||||
MALLOCN (void *, misc_data, misc_data_len);
|
||||
READN (pipe_host2tgt, misc_data, misc_data_len);
|
||||
}
|
||||
uint16_t return_data_len;
|
||||
READN (pipe_host2tgt, &return_data_len, sizeof (uint16_t));
|
||||
void *return_data;
|
||||
if (return_data_len > 0)
|
||||
MALLOCN (void *, return_data, return_data_len);
|
||||
|
||||
/* Run function. */
|
||||
func (buffer_count, buffers, buffers_len, misc_data,
|
||||
misc_data_len, return_data, return_data_len);
|
||||
|
||||
/* Send data to host if any or just send notification. */
|
||||
WRITEN (pipe_tgt2host, return_data_len > 0 ? return_data : &cmd,
|
||||
return_data_len > 0 ? return_data_len : sizeof (cmd_t));
|
||||
|
||||
/* Clean up. */
|
||||
free (buffers);
|
||||
free (buffers_len);
|
||||
if (misc_data_len > 0)
|
||||
free (misc_data);
|
||||
if (return_data_len > 0)
|
||||
free (return_data);
|
||||
}
|
||||
else
|
||||
COIERRORN ("Unrecognizable command from host.");
|
||||
}
|
||||
|
||||
/* Close pipes. */
|
||||
if (close (pipe_host2tgt) < 0)
|
||||
COIERRORN ("Cannot close host-to-target pipe.");
|
||||
if (close (pipe_tgt2host) < 0)
|
||||
COIERRORN ("Cannot close target-to-host pipe.");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
COIRESULT
|
||||
SYMBOL_VERSION (COIProcessWaitForShutdown, 1) ()
|
||||
{
|
||||
COITRACE ("COIProcessWaitForShutdown");
|
||||
|
||||
char *mic_dir = getenv (MIC_DIR_ENV);
|
||||
engine_dir = getenv (MIC_DIR_ENV);
|
||||
char *mic_index = getenv (MIC_INDEX_ENV);
|
||||
char *pipe_host_path, *pipe_target_path;
|
||||
int pipe_host, pipe_target;
|
||||
int cmd_len;
|
||||
pid_t ppid = getppid ();
|
||||
cmd_t cmd;
|
||||
|
||||
assert (mic_dir != NULL && mic_index != NULL);
|
||||
assert (engine_dir != NULL && mic_index != NULL);
|
||||
|
||||
/* Get engine index. */
|
||||
engine_index = atoi (mic_index);
|
||||
|
||||
/* Open pipes. */
|
||||
MALLOC (char *, pipe_host_path,
|
||||
strlen (PIPE_HOST_PATH) + strlen (mic_dir) + 1);
|
||||
MALLOC (char *, pipe_target_path,
|
||||
strlen (PIPE_TARGET_PATH) + strlen (mic_dir) + 1);
|
||||
sprintf (pipe_host_path, "%s" PIPE_HOST_PATH, mic_dir);
|
||||
sprintf (pipe_target_path, "%s" PIPE_TARGET_PATH, mic_dir);
|
||||
pipe_host = open (pipe_host_path, O_CLOEXEC | O_WRONLY);
|
||||
if (pipe_host < 0)
|
||||
COIERROR ("Cannot open target-to-host pipe.");
|
||||
pipe_target = open (pipe_target_path, O_CLOEXEC | O_RDONLY);
|
||||
if (pipe_target < 0)
|
||||
COIERROR ("Cannot open host-to-target pipe.");
|
||||
/* Open main pipes. */
|
||||
char *pipe_host2tgt_path, *pipe_tgt2host_path;
|
||||
MALLOC (char *, pipe_host2tgt_path,
|
||||
strlen (engine_dir) + sizeof (PIPE_HOST2TGT_NAME "mainpipe"));
|
||||
MALLOC (char *, pipe_tgt2host_path,
|
||||
strlen (engine_dir) + sizeof (PIPE_TGT2HOST_NAME "mainpipe"));
|
||||
sprintf (pipe_host2tgt_path, "%s" PIPE_HOST2TGT_NAME "mainpipe", engine_dir);
|
||||
sprintf (pipe_tgt2host_path, "%s" PIPE_TGT2HOST_NAME "mainpipe", engine_dir);
|
||||
int pipe_host2tgt = open (pipe_host2tgt_path, O_CLOEXEC | O_RDONLY);
|
||||
if (pipe_host2tgt < 0)
|
||||
COIERROR ("Cannot open host-to-target main pipe.");
|
||||
int pipe_tgt2host = open (pipe_tgt2host_path, O_CLOEXEC | O_WRONLY);
|
||||
if (pipe_tgt2host < 0)
|
||||
COIERROR ("Cannot open target-to-host main pipe.");
|
||||
|
||||
/* Clean up. */
|
||||
free (pipe_host_path);
|
||||
free (pipe_target_path);
|
||||
free (pipe_host2tgt_path);
|
||||
free (pipe_tgt2host_path);
|
||||
|
||||
/* Handler. */
|
||||
while (1)
|
||||
{
|
||||
/* Read and execute command. */
|
||||
cmd = CMD_SHUTDOWN;
|
||||
cmd_len = read (pipe_target, &cmd, sizeof (cmd_t));
|
||||
cmd_t cmd = CMD_SHUTDOWN;
|
||||
int cmd_len = read (pipe_host2tgt, &cmd, sizeof (cmd_t));
|
||||
if (cmd_len != sizeof (cmd_t) && cmd_len != 0)
|
||||
COIERROR ("Cannot read from pipe.");
|
||||
COIERROR ("Cannot read from main pipe.");
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
|
@ -139,34 +234,33 @@ SYMBOL_VERSION (COIProcessWaitForShutdown, 1) ()
|
|||
void *dest, *source;
|
||||
|
||||
/* Receive data from host. */
|
||||
READ (pipe_target, &dest, sizeof (void *));
|
||||
READ (pipe_target, &source, sizeof (void *));
|
||||
READ (pipe_target, &len, sizeof (uint64_t));
|
||||
READ (pipe_host2tgt, &dest, sizeof (void *));
|
||||
READ (pipe_host2tgt, &source, sizeof (void *));
|
||||
READ (pipe_host2tgt, &len, sizeof (uint64_t));
|
||||
|
||||
/* Copy. */
|
||||
memcpy (dest, source, len);
|
||||
|
||||
/* Notify host about completion. */
|
||||
WRITE (pipe_host, &cmd, sizeof (cmd_t));
|
||||
WRITE (pipe_tgt2host, &cmd, sizeof (cmd_t));
|
||||
|
||||
break;
|
||||
}
|
||||
case CMD_BUFFER_MAP:
|
||||
{
|
||||
char *name;
|
||||
int fd;
|
||||
size_t len;
|
||||
uint64_t buffer_len;
|
||||
void *buffer;
|
||||
|
||||
/* Receive data from host. */
|
||||
READ (pipe_target, &len, sizeof (size_t));
|
||||
READ (pipe_host2tgt, &len, sizeof (size_t));
|
||||
MALLOC (char *, name, len);
|
||||
READ (pipe_target, name, len);
|
||||
READ (pipe_target, &buffer_len, sizeof (uint64_t));
|
||||
READ (pipe_host2tgt, name, len);
|
||||
READ (pipe_host2tgt, &buffer_len, sizeof (uint64_t));
|
||||
|
||||
/* Open shared memory. */
|
||||
fd = shm_open (name, O_CLOEXEC | O_RDWR, S_IRUSR | S_IWUSR);
|
||||
int fd = shm_open (name, O_CLOEXEC | O_RDWR, S_IRUSR | S_IWUSR);
|
||||
if (fd < 0)
|
||||
COIERROR ("Cannot open shared memory.");
|
||||
|
||||
|
@ -177,8 +271,8 @@ SYMBOL_VERSION (COIProcessWaitForShutdown, 1) ()
|
|||
COIERROR ("Cannot map shared memory.");
|
||||
|
||||
/* Send data to host. */
|
||||
WRITE (pipe_host, &fd, sizeof (int));
|
||||
WRITE (pipe_host, &buffer, sizeof (void *));
|
||||
WRITE (pipe_tgt2host, &fd, sizeof (int));
|
||||
WRITE (pipe_tgt2host, &buffer, sizeof (void *));
|
||||
|
||||
/* Clean up. */
|
||||
free (name);
|
||||
|
@ -192,9 +286,9 @@ SYMBOL_VERSION (COIProcessWaitForShutdown, 1) ()
|
|||
void *buffer;
|
||||
|
||||
/* Receive data from host. */
|
||||
READ (pipe_target, &fd, sizeof (int));
|
||||
READ (pipe_target, &buffer, sizeof (void *));
|
||||
READ (pipe_target, &buffer_len, sizeof (uint64_t));
|
||||
READ (pipe_host2tgt, &fd, sizeof (int));
|
||||
READ (pipe_host2tgt, &buffer, sizeof (void *));
|
||||
READ (pipe_host2tgt, &buffer_len, sizeof (uint64_t));
|
||||
|
||||
/* Unmap buffer. */
|
||||
if (munmap (buffer, buffer_len) < 0)
|
||||
|
@ -205,7 +299,7 @@ SYMBOL_VERSION (COIProcessWaitForShutdown, 1) ()
|
|||
COIERROR ("Cannot close shared memory file.");
|
||||
|
||||
/* Notify host about completion. */
|
||||
WRITE (pipe_host, &cmd, sizeof (cmd_t));
|
||||
WRITE (pipe_tgt2host, &cmd, sizeof (cmd_t));
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -213,20 +307,19 @@ SYMBOL_VERSION (COIProcessWaitForShutdown, 1) ()
|
|||
{
|
||||
char *name;
|
||||
size_t len;
|
||||
void *ptr;
|
||||
|
||||
/* Receive data from host. */
|
||||
READ (pipe_target, &len, sizeof (size_t));
|
||||
READ (pipe_host2tgt, &len, sizeof (size_t));
|
||||
MALLOC (char *, name, len);
|
||||
READ (pipe_target, name, len);
|
||||
READ (pipe_host2tgt, name, len);
|
||||
|
||||
/* Find function. */
|
||||
ptr = dlsym (RTLD_DEFAULT, name);
|
||||
void *ptr = dlsym (RTLD_DEFAULT, name);
|
||||
if (ptr == NULL)
|
||||
COIERROR ("Cannot find symbol %s.", name);
|
||||
|
||||
/* Send data to host. */
|
||||
WRITE (pipe_host, &ptr, sizeof (void *));
|
||||
WRITE (pipe_tgt2host, &ptr, sizeof (void *));
|
||||
|
||||
/* Clean up. */
|
||||
free (name);
|
||||
|
@ -237,20 +330,19 @@ SYMBOL_VERSION (COIProcessWaitForShutdown, 1) ()
|
|||
{
|
||||
char *lib_path;
|
||||
size_t len;
|
||||
void *handle;
|
||||
|
||||
/* Receive data from host. */
|
||||
READ (pipe_target, &len, sizeof (size_t));
|
||||
READ (pipe_host2tgt, &len, sizeof (size_t));
|
||||
MALLOC (char *, lib_path, len);
|
||||
READ (pipe_target, lib_path, len);
|
||||
READ (pipe_host2tgt, lib_path, len);
|
||||
|
||||
/* Open library. */
|
||||
handle = dlopen (lib_path, RTLD_LAZY | RTLD_GLOBAL);
|
||||
void *handle = dlopen (lib_path, RTLD_LAZY | RTLD_GLOBAL);
|
||||
if (handle == NULL)
|
||||
COIERROR ("Cannot load %s: %s", lib_path, dlerror ());
|
||||
|
||||
/* Send data to host. */
|
||||
WRITE (pipe_host, &handle, sizeof (void *));
|
||||
WRITE (pipe_tgt2host, &handle, sizeof (void *));
|
||||
|
||||
/* Clean up. */
|
||||
free (lib_path);
|
||||
|
@ -261,67 +353,30 @@ SYMBOL_VERSION (COIProcessWaitForShutdown, 1) ()
|
|||
{
|
||||
/* Receive data from host. */
|
||||
void *handle;
|
||||
READ (pipe_target, &handle, sizeof (void *));
|
||||
READ (pipe_host2tgt, &handle, sizeof (void *));
|
||||
|
||||
dlclose (handle);
|
||||
|
||||
break;
|
||||
}
|
||||
case CMD_RUN_FUNCTION:
|
||||
case CMD_PIPELINE_CREATE:
|
||||
{
|
||||
uint16_t misc_data_len, return_data_len;
|
||||
uint32_t buffer_count, i;
|
||||
uint64_t *buffers_len, size;
|
||||
void *ptr;
|
||||
void **buffers, *misc_data, *return_data;
|
||||
|
||||
void (*func) (uint32_t, void **, uint64_t *,
|
||||
void *, uint16_t, void*, uint16_t);
|
||||
|
||||
/* Receive data from host. */
|
||||
READ (pipe_target, &func, sizeof (void *));
|
||||
READ (pipe_target, &buffer_count, sizeof (uint32_t));
|
||||
MALLOC (void **, buffers, buffer_count * sizeof (void *));
|
||||
MALLOC (uint64_t *, buffers_len, buffer_count * sizeof (uint64_t));
|
||||
|
||||
for (i = 0; i < buffer_count; i++)
|
||||
{
|
||||
READ (pipe_target, &(buffers_len[i]), sizeof (uint64_t));
|
||||
READ (pipe_target, &(buffers[i]), sizeof (void *));
|
||||
}
|
||||
READ (pipe_target, &misc_data_len, sizeof (uint16_t));
|
||||
if (misc_data_len > 0)
|
||||
{
|
||||
MALLOC (void *, misc_data, misc_data_len);
|
||||
READ (pipe_target, misc_data, misc_data_len);
|
||||
}
|
||||
READ (pipe_target, &return_data_len, sizeof (uint16_t));
|
||||
if (return_data_len > 0)
|
||||
MALLOC (void *, return_data, return_data_len);
|
||||
|
||||
/* Run function. */
|
||||
func (buffer_count, buffers, buffers_len, misc_data,
|
||||
misc_data_len, return_data, return_data_len);
|
||||
|
||||
/* Send data to host if any or just send notification. */
|
||||
WRITE (pipe_host, return_data_len > 0 ? return_data : &cmd,
|
||||
return_data_len > 0 ? return_data_len : sizeof (cmd_t));
|
||||
|
||||
/* Clean up. */
|
||||
free (buffers);
|
||||
free (buffers_len);
|
||||
if (misc_data_len > 0)
|
||||
free (misc_data);
|
||||
if (return_data_len > 0)
|
||||
free (return_data);
|
||||
uint32_t *pipeline_num = (uint32_t *) malloc (sizeof (uint32_t));
|
||||
READ (pipe_host2tgt, pipeline_num, sizeof (*pipeline_num));
|
||||
|
||||
/* Create a new thread for the pipeline. */
|
||||
pthread_t thread;
|
||||
if (pthread_create (&thread, NULL, pipeline_thread_routine,
|
||||
pipeline_num))
|
||||
COIERROR ("Cannot create new thread.");
|
||||
break;
|
||||
}
|
||||
case CMD_SHUTDOWN:
|
||||
if (close (pipe_host) < 0)
|
||||
COIERROR ("Cannot close target-to-host pipe.");
|
||||
if (close (pipe_target) < 0)
|
||||
COIERROR ("Cannot close host-to-target pipe.");
|
||||
if (close (pipe_host2tgt) < 0)
|
||||
COIERROR ("Cannot close host-to-target main pipe.");
|
||||
if (close (pipe_tgt2host) < 0)
|
||||
COIERROR ("Cannot close target-to-host main pipe.");
|
||||
return COI_SUCCESS;
|
||||
default:
|
||||
COIERROR ("Unrecognizable command from host.");
|
||||
|
|
|
@ -41,6 +41,16 @@
|
|||
return COI_ERROR; \
|
||||
}
|
||||
|
||||
/* Like COIERROR, but return NULL instead of COIRESULT. */
|
||||
#define COIERRORN(...) \
|
||||
{ \
|
||||
fprintf (stderr, "COI ERROR - TARGET: "); \
|
||||
fprintf (stderr, __VA_ARGS__); \
|
||||
fprintf (stderr, "\n"); \
|
||||
perror (NULL); \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#define COITRACE(...) \
|
||||
{ \
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -41,6 +41,16 @@
|
|||
return COI_ERROR; \
|
||||
}
|
||||
|
||||
/* Like COIERROR, but return NULL instead of COIRESULT. */
|
||||
#define COIERRORN(...) \
|
||||
{ \
|
||||
fprintf (stderr, "COI ERROR - HOST: "); \
|
||||
fprintf (stderr, __VA_ARGS__); \
|
||||
fprintf (stderr, "\n"); \
|
||||
perror (NULL); \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#define COITRACE(...) \
|
||||
{ \
|
||||
|
|
Loading…
Add table
Reference in a new issue