// If we used a local async info object we want synchronous behavior.
// In that case, and assuming the current status code is OK, we will
// synchronize explicitly when the object is deleted.
- if (AsyncInfoPtr == &LocalAsyncInfo && !Err)
+ if (AsyncInfoPtr == &LocalAsyncInfo && LocalAsyncInfo.Queue && !Err)
Err = Device.synchronize(&LocalAsyncInfo);
}
DeviceEnvironment.DynamicMemSize = OMPX_SharedMemorySize;
// Create the metainfo of the device environment global.
- GlobalTy DeviceEnvGlobal("omptarget_device_environment",
- sizeof(DeviceEnvironmentTy), &DeviceEnvironment);
+ GlobalTy DevEnvGlobal("omptarget_device_environment",
+ sizeof(DeviceEnvironmentTy), &DeviceEnvironment);
// Write device environment values to the device.
- GenericGlobalHandlerTy &GlobalHandler = Plugin.getGlobalHandler();
- return GlobalHandler.writeGlobalToDevice(*this, Image, DeviceEnvGlobal);
+ GenericGlobalHandlerTy &GHandler = Plugin.getGlobalHandler();
+ if (auto Err = GHandler.writeGlobalToDevice(*this, Image, DevEnvGlobal)) {
+ DP("Missing symbol %s, continue execution anyway.\n",
+ DevEnvGlobal.getName().data());
+ consumeError(std::move(Err));
+ }
+ return Plugin::success();
}
Error GenericDeviceTy::registerOffloadEntries(DeviceImageTy &Image) {
/// create a new resource on the ctor, but on the create() function instead.
struct GenericDeviceResourceRef {
/// Create a new resource and stores a reference.
- virtual Error create() = 0;
+ virtual Error create(GenericDeviceTy &Device) = 0;
/// Destroy and release the resources pointed by the reference.
- virtual Error destroy() = 0;
+ virtual Error destroy(GenericDeviceTy &Device) = 0;
protected:
~GenericDeviceResourceRef() = default;
/// Get resource from the pool or create new resources.
ResourceRef getResource() {
const std::lock_guard<std::mutex> Lock(Mutex);
+
+ assert(NextAvailable <= ResourcePool.size() &&
+ "Resource pool is corrupted");
+
if (NextAvailable == ResourcePool.size()) {
// By default we double the resource pool every time.
if (auto Err = ResourcePoolTy::resizeResourcePool(NextAvailable * 2)) {
/// Return resource to the pool.
void returnResource(ResourceRef Resource) {
const std::lock_guard<std::mutex> Lock(Mutex);
+
+ assert(NextAvailable > 0 && "Resource pool is corrupted");
ResourcePool[--NextAvailable] = Resource;
}
if (OldSize < NewSize) {
// Create new resources.
for (uint32_t I = OldSize; I < NewSize; ++I) {
- if (auto Err = ResourcePool[I].create())
+ if (auto Err = ResourcePool[I].create(Device))
return Err;
}
} else {
// Destroy the obsolete resources.
for (uint32_t I = NewSize; I < OldSize; ++I) {
- if (auto Err = ResourcePool[I].destroy())
+ if (auto Err = ResourcePool[I].destroy(Device))
return Err;
}
}
/// Create a new stream and save the reference. The reference must be empty
/// before calling to this function.
- Error create() override {
+ Error create(GenericDeviceTy &Device) override {
if (Stream)
return Plugin::error("Creating an existing stream");
/// Destroy the referenced stream and invalidate the reference. The reference
/// must be to a valid stream before calling to this function.
- Error destroy() override {
+ Error destroy(GenericDeviceTy &Device) override {
if (!Stream)
return Plugin::error("Destroying an invalid stream");
/// Create a new event and save the reference. The reference must be empty
/// before calling to this function.
- Error create() override {
+ Error create(GenericDeviceTy &Device) override {
if (Event)
return Plugin::error("Creating an existing event");
/// Destroy the referenced event and invalidate the reference. The reference
/// must be to a valid event before calling to this function.
- Error destroy() override {
+ Error destroy(GenericDeviceTy &Device) override {
if (!Event)
return Plugin::error("Destroying an invalid event");