]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - liboffloadmic/runtime/ofldbegin.cpp
backport: Makefile.am (liboffloadmic_host_la_DEPENDENCIES): Remove libcoi_host and...
[thirdparty/gcc.git] / liboffloadmic / runtime / ofldbegin.cpp
index 6f4b536f5b732bbe636f9335de7cb4a94201f5fc..236500d011a7396c1fb8c98211444032db850dcd 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (c) 2014 Intel Corporation.  All Rights Reserved.
+    Copyright (c) 2014-2015 Intel Corporation.  All Rights Reserved.
 
     Redistribution and use in source and binary forms, with or without
     modification, are permitted provided that the following conditions
@@ -29,7 +29,7 @@
 
 
 #if HOST_LIBRARY
-#include "offload_host.h"
+#include "offload_table.h"
 #include "offload_myo_host.h"
 #else
 #include "compiler_if_target.h"
 #include "offload_myo_target.h"
 #endif
 
+// Initializes library and registers specified offload image.
+// Don't use this declarations from offload_host.h as offload_table.h
+// is used instead of it. Using offload_host.h contradicts with
+// STL library compiled with VS2010.
+extern "C" bool __offload_register_image(const void* image);
+extern "C" void __offload_unregister_image(const void* image);
+extern "C" bool __offload_target_image_is_executable(const void *image);
+
 #ifdef TARGET_WINNT
 #define ALLOCATE(name) __declspec(allocate(name))
 #define DLL_LOCAL
@@ -110,33 +118,127 @@ static VarList::Node __offload_var_node = {
 #ifdef MYO_SUPPORT
 
 // offload myo shared var section prolog
+// first element is empty
 ALLOCATE(OFFLOAD_MYO_SHARED_TABLE_SECTION_START)
 #ifdef TARGET_WINNT
 __declspec(align(sizeof(SharedTableEntry)))
 #endif // TARGET_WINNT
-static SharedTableEntry __offload_myo_shared_table_start = { 0 };
+static MYOVarTable::Entry __offload_myo_shared_var_start = { 0 };
+
+// list element for the current module
+// table entry pointer skips the empty first entry
+static MYOVarTableList::Node __offload_myo_shared_var_node = {
+    { &__offload_myo_shared_var_start + 1 },
+    0, 0
+};
+
+// offload myo shared vtable section prolog
+// first element is empty
+ALLOCATE(OFFLOAD_MYO_SHARED_VTABLE_SECTION_START)
+#ifdef TARGET_WINNT
+__declspec(align(sizeof(SharedTableEntry)))
+#endif // TARGET_WINNT
+static MYOVarTable::Entry __offload_myo_shared_vtable_start = { 0 };
+
+// list element for the current module
+// table entry pointer skips the empty first entry
+static MYOVarTableList::Node __offload_myo_shared_vtable_node = {
+    { &__offload_myo_shared_vtable_start + 1 },
+    0, 0
+};
 
-#if HOST_LIBRARY
 // offload myo shared var init section prolog
+// first element is empty
 ALLOCATE(OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START)
 #ifdef TARGET_WINNT
 __declspec(align(sizeof(InitTableEntry)))
 #endif // TARGET_WINNT
-static InitTableEntry __offload_myo_shared_init_table_start = { 0 };
+static MYOInitTable::Entry __offload_myo_init_table_start = { 0 };
+
+// list element for the current module
+// table entry pointer skips the empty first entry
+static MYOInitTableList::Node __offload_myo_init_table_node = {
+    { &__offload_myo_init_table_start + 1 },
+    0, 0
+};
+
+// The functions and variables needed for a built-in
+// remote function entry for vtable initialization on MIC
+
+#if !HOST_LIBRARY
+MyoError __offload_init_vtables(void)
+{
+    SharedTableEntry *t_start;
+
+    //OFFLOAD_DEBUG_TRACE(3, "%s\n", __func__);
+    t_start = &__offload_myo_shared_vtable_start + 1;
+    //OFFLOAD_DEBUG_TRACE(3, "%s(%p)\n", __func__, t_start);
+    while (t_start->varName != 0) {
+        //OFFLOAD_DEBUG_TRACE(4,
+        //    "myo shared vtable \"%s\" &myo_ptr = %p myo_ptr = %p\n",
+        //    t_start->varName,
+        //    (void *)(t_start->sharedAddr),
+        //    ((void **)(t_start->sharedAddr))[0]);
+        t_start++;
+    }
+
+    __offload_myo_shared_init_table_process(
+        &__offload_myo_init_table_start + 1);
+    return MYO_SUCCESS;
+}
+#endif  // !HOST_LIBRARY
+
+static void vtable_initializer()
+{
+}
+
+#if !HOST_LIBRARY
+static MyoError vtable_initializer_wrapper()
+{
+    __offload_myoAcquire();
+    __offload_init_vtables();
+    __offload_myoRelease();
+    return MYO_SUCCESS;
+}
 #endif
 
+static void* __offload_vtable_initializer_thunk_ptr = 0;
+
 // offload myo fptr section prolog
+// first element is pre-initialized to the MIC vtable initializer
 ALLOCATE(OFFLOAD_MYO_FPTR_TABLE_SECTION_START)
 #ifdef TARGET_WINNT
 __declspec(align(sizeof(FptrTableEntry)))
 #endif // TARGET_WINNT
-static FptrTableEntry __offload_myo_fptr_table_start = { 0 };
+static MYOFuncTable::Entry __offload_myo_fptr_table_start = {
+#if HOST_LIBRARY
+    "--vtable_initializer--",
+    (void*)&vtable_initializer,
+    (void*)&__offload_vtable_initializer_thunk_ptr,
+#ifdef TARGET_WINNT
+    // Dummy to pad up to 32 bytes
+    0
+#endif // TARGET_WINNT
+#else  // HOST_LIBRARY
+    "--vtable_initializer--",
+    (void*)&vtable_initializer,
+    (void*)&vtable_initializer_wrapper,
+    &__offload_vtable_initializer_thunk_ptr,
+#endif // HOST_LIBRARY
+};
+
+// list element for the current module
+static MYOFuncTableList::Node __offload_myo_fptr_table_node = {
+    { &__offload_myo_fptr_table_start },
+    0, 0
+};
 
 #endif // MYO_SUPPORT
 
 // init/fini code which adds/removes local lookup data to/from the global list
 
 static void offload_fini();
+static void offload_fini_so();
 
 #ifndef TARGET_WINNT
 static void offload_init() __attribute__((constructor(101)));
@@ -150,35 +252,81 @@ static void (*addressof_offload_init)() = offload_init;
 
 static void offload_init()
 {
+    bool success;
+
     // register offload tables
     __offload_register_tables(&__offload_entry_node,
                               &__offload_func_node,
                               &__offload_var_node);
 
 #if HOST_LIBRARY
-    __offload_register_image(&__offload_target_image);
-    atexit(offload_fini);
+    success = __offload_register_image(&__offload_target_image);
+    if (!success)
+    {
+        return;
+    }
 #endif // HOST_LIBRARY
-
 #ifdef MYO_SUPPORT
-    __offload_myoRegisterTables(
 #if HOST_LIBRARY
-        &__offload_myo_shared_init_table_start + 1,
-#endif // HOST_LIBRARY
-        &__offload_myo_shared_table_start + 1,
-        &__offload_myo_fptr_table_start + 1
+    // If this was the main program register main atexit routine
+    if (__offload_myoProcessTables(
+            &__offload_target_image,
+            &__offload_myo_init_table_node,
+            &__offload_myo_shared_var_node,
+            &__offload_myo_shared_vtable_node,
+            &__offload_myo_fptr_table_node))
+    {
+        atexit(offload_fini);
+#ifdef TARGET_WINNT
+    } else {
+        atexit(offload_fini_so);
+#endif
+    }
+#else // HOST_LIBRARY
+    __offload_myoProcessTables(
+        &__offload_myo_init_table_start + 1,
+        &__offload_myo_shared_var_start + 1,
+        &__offload_myo_shared_vtable_start + 1,
+        &__offload_myo_fptr_table_start
     );
+#endif // HOST_LIBRARY
 #endif // MYO_SUPPORT
 }
 
+#ifndef TARGET_WINNT
+static void offload_fini_so() __attribute__((destructor(101)));
+#else // TARGET_WINNT
+static void offload_init_so();
+#endif // TARGET_WINNT
+
 static void offload_fini()
 {
 #if HOST_LIBRARY
     __offload_unregister_image(&__offload_target_image);
 #endif // HOST_LIBRARY
+}
 
-    // unregister offload tables
+static void offload_fini_so()
+{
+    // Offload and MYO tables need to be removed from list
+    // to prevent invalid accesses after dlclose
+    // Remove offload tables
     __offload_unregister_tables(&__offload_entry_node,
                                 &__offload_func_node,
                                 &__offload_var_node);
+#if HOST_LIBRARY
+   if(!__offload_target_image_is_executable(&__offload_target_image)) {
+      __offload_unregister_image(&__offload_target_image);
+   }
+#endif
+#ifdef MYO_SUPPORT
+#if HOST_LIBRARY
+    // Remove MYO tables
+    __offload_myoRemoveTables(
+        &__offload_myo_init_table_node,
+        &__offload_myo_shared_var_node,
+        &__offload_myo_shared_vtable_node,
+        &__offload_myo_fptr_table_node);
+#endif // HOST_LIBRARY
+#endif // MYO_SUPPORT
 }