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:
Ilya Verbin 2015-09-29 14:11:16 +00:00 committed by Ilya Verbin
parent b59882293f
commit 44799f87c3
7 changed files with 1121 additions and 606 deletions

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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.");

View file

@ -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

View file

@ -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(...) \
{ \