These are the intelmic plugin specific parts (actually beneath liboffloadmic instead of libgomp).
The changes are basically to expose the return value of offload() back to libgomp. I only checked parts of the plugin, it appears that there may still be code in the liboffloadmic runtime that can call exit() while holding the lock, so Intel folks might want to audit more thoroughly later. Chung-Lin * plugin/libgomp-plugin-intelmic.cpp (offload): Change return type to bool, adjust return code. (GOMP_OFFLOAD_init_device): Likewise. (GOMP_OFFLOAD_fini_device): Likewise. (get_target_table): Likewise. (offload_image): Likwise. (GOMP_OFFLOAD_load_image): Adjust call to offload_image(), change exit() to return error. (GOMP_OFFLOAD_alloc): Change return type to bool, change to use out parameter to return allocated pointer. (GOMP_OFFLOAD_free): Change return type to bool, adjust return code. (GOMP_OFFLOAD_host2dev): Likewise. (GOMP_OFFLOAD_dev2host): Likewise.
Index: liboffloadmic/plugin/libgomp-plugin-intelmic.cpp =================================================================== --- liboffloadmic/plugin/libgomp-plugin-intelmic.cpp (revision 227257) +++ liboffloadmic/plugin/libgomp-plugin-intelmic.cpp (working copy) @@ -184,17 +184,18 @@ GOMP_OFFLOAD_get_num_devices (void) return num_devices; } -static void +static bool offload (const char *file, uint64_t line, int device, const char *name, int num_vars, VarDesc *vars, VarDesc2 *vars2) { OFFLOAD ofld = __offload_target_acquire1 (&device, file, line); if (ofld) - __offload_offload1 (ofld, name, 0, num_vars, vars, vars2, 0, NULL, NULL); + return __offload_offload1 (ofld, name, 0, num_vars, vars, vars2, 0, + NULL, NULL); else { - fprintf (stderr, "%s:%d: Offload target acquire failed\n", file, line); - exit (1); + GOMP_PLUGIN_error ("%s:%d: Offload target acquire failed\n", file, line); + return false; } } @@ -206,24 +207,25 @@ register_main_image () /* liboffloadmic loads and runs offload_target_main on all available devices during a first call to offload (). */ -extern "C" void +extern "C" bool GOMP_OFFLOAD_init_device (int device) { TRACE (""); pthread_once (&main_image_is_registered, register_main_image); - offload (__FILE__, __LINE__, device, "__offload_target_init_proc", 0, - NULL, NULL); + return offload (__FILE__, __LINE__, device, "__offload_target_init_proc", 0, + NULL, NULL); } -extern "C" void +extern "C" bool GOMP_OFFLOAD_fini_device (int device) { TRACE (""); /* Unreachable for GOMP_OFFLOAD_CAP_OPENMP_400. */ abort (); + return true; } -static void +static bool get_target_table (int device, int &num_funcs, int &num_vars, void **&table) { VarDesc vd1[2] = { vd_tgt2host, vd_tgt2host }; @@ -233,8 +235,9 @@ get_target_table (int device, int &num_funcs, int vd1[1].size = sizeof (num_vars); VarDesc2 vd1g[2] = { { "num_funcs", 0 }, { "num_vars", 0 } }; - offload (__FILE__, __LINE__, device, "__offload_target_table_p1", 2, - vd1, vd1g); + if (!offload (__FILE__, __LINE__, device, "__offload_target_table_p1", 2, + vd1, vd1g)) + return false; int table_size = num_funcs + 2 * num_vars; if (table_size > 0) @@ -247,15 +250,16 @@ get_target_table (int device, int &num_funcs, int vd2.size = table_size * sizeof (void *); VarDesc2 vd2g = { "table", 0 }; - offload (__FILE__, __LINE__, device, "__offload_target_table_p2", 1, - &vd2, &vd2g); + return offload (__FILE__, __LINE__, device, "__offload_target_table_p2", + 1, &vd2, &vd2g); } + return true; } /* Offload TARGET_IMAGE to all available devices and fill address_table with corresponding target addresses. */ -static void +static bool offload_image (const void *target_image) { struct TargetImage { @@ -277,8 +281,8 @@ offload_image (const void *target_image) + image_size); if (!image) { - fprintf (stderr, "%s: Can't allocate memory\n", __FILE__); - exit (1); + GOMP_PLUGIN_error ("%s: Can't allocate memory\n", __FILE__); + return false; } image->size = image_size; @@ -291,13 +295,14 @@ offload_image (const void *target_image) /* Receive tables for target_image from all devices. */ DevAddrVect dev_table; + bool ret = true; for (int dev = 0; dev < num_devices; dev++) { int num_funcs = 0; int num_vars = 0; void **table = NULL; - get_target_table (dev, num_funcs, num_vars, table); + ret &= get_target_table (dev, num_funcs, num_vars, table); AddrVect curr_dev_table; @@ -326,6 +331,7 @@ offload_image (const void *target_image) address_table->insert (std::make_pair (target_image, dev_table)); free (image); + return ret; } /* Return the libgomp version number we're compatible with. There is @@ -351,15 +357,19 @@ GOMP_OFFLOAD_load_image (int device, const unsigne /* If target_image is already present in address_table, then there is no need to offload it. */ if (address_table->count (target_image) == 0) - offload_image (target_image); + { + /* If fail, return -1 as error code. */ + if (!offload_image (target_image)) + return -1; + } AddrVect *curr_dev_table = &(*address_table)[target_image][device]; int table_size = curr_dev_table->size (); addr_pair *table = (addr_pair *) malloc (table_size * sizeof (addr_pair)); if (table == NULL) { - fprintf (stderr, "%s: Can't allocate memory\n", __FILE__); - exit (1); + GOMP_PLUGIN_error ("%s: Can't allocate memory\n", __FILE__); + return -1; } std::copy (curr_dev_table->begin (), curr_dev_table->end (), table); @@ -382,8 +392,8 @@ GOMP_OFFLOAD_unload_image (int device, unsigned ve address_table->erase (target_image); } -extern "C" void * -GOMP_OFFLOAD_alloc (int device, size_t size) +extern "C" bool +GOMP_OFFLOAD_alloc (int device, size_t size, void **ptr) { TRACE ("(size = %d)", size); @@ -395,12 +405,15 @@ GOMP_OFFLOAD_unload_image (int device, unsigned ve vd1[1].size = sizeof (void *); VarDesc2 vd1g[2] = { { "size", 0 }, { "tgt_ptr", 0 } }; - offload (__FILE__, __LINE__, device, "__offload_target_alloc", 2, vd1, vd1g); + if (!offload (__FILE__, __LINE__, device, "__offload_target_alloc", 2, + vd1, vd1g)) + return false; - return tgt_ptr; + *ptr = tgt_ptr; + return true; } -extern "C" void +extern "C" bool GOMP_OFFLOAD_free (int device, void *tgt_ptr) { TRACE ("(tgt_ptr = %p)", tgt_ptr); @@ -410,16 +423,17 @@ GOMP_OFFLOAD_free (int device, void *tgt_ptr) vd1.size = sizeof (void *); VarDesc2 vd1g = { "tgt_ptr", 0 }; - offload (__FILE__, __LINE__, device, "__offload_target_free", 1, &vd1, &vd1g); + return offload (__FILE__, __LINE__, device, "__offload_target_free", 1, + &vd1, &vd1g); } -extern "C" void * +extern "C" bool GOMP_OFFLOAD_host2dev (int device, void *tgt_ptr, const void *host_ptr, size_t size) { TRACE ("(tgt_ptr = %p, host_ptr = %p, size = %d)", tgt_ptr, host_ptr, size); if (!size) - return tgt_ptr; + return true; VarDesc vd1[2] = { vd_host2tgt, vd_host2tgt }; vd1[0].ptr = &tgt_ptr; @@ -428,27 +442,26 @@ GOMP_OFFLOAD_host2dev (int device, void *tgt_ptr, vd1[1].size = sizeof (size); VarDesc2 vd1g[2] = { { "tgt_ptr", 0 }, { "size", 0 } }; - offload (__FILE__, __LINE__, device, "__offload_target_host2tgt_p1", 2, - vd1, vd1g); + if (!offload (__FILE__, __LINE__, device, "__offload_target_host2tgt_p1", 2, + vd1, vd1g)) + return false; VarDesc vd2 = vd_host2tgt; vd2.ptr = (void *) host_ptr; vd2.size = size; VarDesc2 vd2g = { "var", 0 }; - offload (__FILE__, __LINE__, device, "__offload_target_host2tgt_p2", 1, - &vd2, &vd2g); - - return tgt_ptr; + return offload (__FILE__, __LINE__, device, "__offload_target_host2tgt_p2", 1, + &vd2, &vd2g); } -extern "C" void * +extern "C" bool GOMP_OFFLOAD_dev2host (int device, void *host_ptr, const void *tgt_ptr, size_t size) { TRACE ("(host_ptr = %p, tgt_ptr = %p, size = %d)", host_ptr, tgt_ptr, size); if (!size) - return host_ptr; + return true; VarDesc vd1[2] = { vd_host2tgt, vd_host2tgt }; vd1[0].ptr = &tgt_ptr; @@ -457,18 +470,17 @@ GOMP_OFFLOAD_dev2host (int device, void *host_ptr, vd1[1].size = sizeof (size); VarDesc2 vd1g[2] = { { "tgt_ptr", 0 }, { "size", 0 } }; - offload (__FILE__, __LINE__, device, "__offload_target_tgt2host_p1", 2, - vd1, vd1g); + if (!offload (__FILE__, __LINE__, device, "__offload_target_tgt2host_p1", 2, + vd1, vd1g)) + return false; VarDesc vd2 = vd_tgt2host; vd2.ptr = (void *) host_ptr; vd2.size = size; VarDesc2 vd2g = { "var", 0 }; - offload (__FILE__, __LINE__, device, "__offload_target_tgt2host_p2", 1, - &vd2, &vd2g); - - return host_ptr; + return offload (__FILE__, __LINE__, device, "__offload_target_tgt2host_p2", 1, + &vd2, &vd2g); } extern "C" void