Initial exception support for signals.

Also separate signal ABI block allocations from the runtime interface object.

Change-Id: If16763338db664f29163a1348f8f4c38cf0597b2


[ROCm/ROCR-Runtime commit: 2732b18092]
这个提交包含在:
Sean Keely
2017-07-05 19:33:37 -05:00
父节点 76e67099b3
当前提交 550547f404
修改 11 个文件,包含 543 行新增192 行删除
@@ -80,10 +80,6 @@ class Shared : public BaseShared {
shared_object_ =
reinterpret_cast<T*>(allocate_(sizeof(T), Max(__alignof(T), Align), 0));
assert(shared_object_ != NULL && "Failed on allocating shared_object_");
memset(shared_object_, 0, sizeof(T));
if (shared_object_ != NULL) new (shared_object_) T;
}
@@ -53,7 +53,7 @@ namespace amd {
/// @brief Encapsulates HW Aql Command Processor functionality. It
/// provide the interface for things such as Doorbell register, read,
/// write pointers and a buffer.
class AqlQueue : public core::Queue, public core::Signal {
class AqlQueue : public core::Queue, private core::LocalSignal, public core::Signal {
public:
static __forceinline bool IsType(core::Signal* signal) {
return signal->IsType(&rtti_id_);
@@ -336,12 +336,6 @@ class AqlQueue : public core::Queue, public core::Signal {
return NULL;
}
// 64 byte-aligned allocation and release, for Queue::amd_queue_.
void* operator new(size_t size);
void* operator new(size_t size, void* ptr) { return ptr; }
void operator delete(void* ptr);
void operator delete(void*, void*) {}
protected:
bool _IsA(rtti_t id) const override { return id == &rtti_id_; }
@@ -48,29 +48,61 @@
namespace core {
/// @brief Base class for all classes whose validity can be checked using
/// IsValid() method.
template <uint64_t code>
class Checked {
/// @brief Compares type codes and pointers to check object validity. Used for cast validation.
template <uint64_t code, bool multiProcess = false> class Check final {
public:
typedef Checked<code> CheckedType;
typedef Check<code> CheckType;
Checked() { object_ = uintptr_t(this) ^ uintptr_t(code); }
Checked(const Checked&) { object_ = uintptr_t(this) ^ uintptr_t(code); }
Checked(Checked&&) { object_ = uintptr_t(this) ^ uintptr_t(code); }
Check() { object_ = uintptr_t(this) ^ uintptr_t(code); }
Check(const Check&) { object_ = uintptr_t(this) ^ uintptr_t(code); }
Check(Check&&) { object_ = uintptr_t(this) ^ uintptr_t(code); }
virtual ~Checked() { object_ = NULL; }
~Check() { object_ = NULL; }
const Checked& operator=(Checked&& rhs) { return *this; }
const Checked& operator=(const Checked& rhs) { return *this; }
const Check& operator=(Check&& rhs) { return *this; }
const Check& operator=(const Check& rhs) { return *this; }
bool IsValid() const {
return object_ == (uintptr_t(this) ^ uintptr_t(code));
}
uint64_t check_code() const { return code; }
private:
uintptr_t object_;
};
template <uint64_t code> class Check<code, true> final {
public:
typedef Check<code> CheckType;
Check() { object_ = uintptr_t(code); }
Check(const Check&) { object_ = uintptr_t(code); }
Check(Check&&) { object_ = uintptr_t(code); }
const Check& operator=(Check&& rhs) { return *this; }
const Check& operator=(const Check& rhs) { return *this; }
bool IsValid() const { return object_ == uintptr_t(code); }
uint64_t check_code() const { return code; }
private:
uintptr_t object_;
};
/// @brief Base class for validating objects.
template <uint64_t code> class Checked {
public:
typedef Checked<code> CheckedType;
bool IsValid() const { return id.IsValid(); }
virtual ~Checked() {}
private:
Check<code, false> id;
};
} // namespace core
#endif // header guard
@@ -53,7 +53,7 @@ namespace core {
/// @brief Simple pure memory based signal.
/// @brief See base class Signal.
class DefaultSignal : public Signal {
class DefaultSignal : private LocalSignal, public Signal {
public:
/// @brief Determines if a Signal* can be safely converted to DefaultSignal*
/// via static_cast.
@@ -155,12 +155,6 @@ class DefaultSignal : public Signal {
/// @brief see the base class Signal
__forceinline HsaEvent* EopEvent() { return NULL; }
/// @brief prevent throwing exceptions
void* operator new(size_t size) { return malloc(size); }
/// @brief prevent throwing exceptions
void operator delete(void* ptr) { free(ptr); }
protected:
bool _IsA(rtti_t id) const { return id == &rtti_id_; }
@@ -61,7 +61,7 @@ namespace core {
/// Supports only one waiter for now.
/// KFD changes are needed to support multiple waiters and have device
/// signaling.
class InterruptSignal : public Signal {
class InterruptSignal : private LocalSignal, public Signal {
public:
static HsaEvent* CreateEvent(HSA_EVENTTYPE type, bool manual_reset);
static void DestroyEvent(HsaEvent* evt);
@@ -165,12 +165,6 @@ class InterruptSignal : public Signal {
/// @brief See base class Signal.
__forceinline HsaEvent* EopEvent() { return event_; }
/// @brief prevent throwing exceptions
void* operator new(size_t size) { return malloc(size); }
/// @brief prevent throwing exceptions
void operator delete(void* ptr) { free(ptr); }
protected:
bool _IsA(rtti_t id) const { return id == &rtti_id_; }
@@ -53,6 +53,7 @@
#include "core/inc/checked.h"
#include "core/util/utils.h"
#include "core/util/locks.h"
#include "inc/amd_hsa_signal.h"
@@ -60,54 +61,72 @@ namespace core {
class Agent;
class Signal;
/// @brief Helper structure to simplify conversion of amd_signal_t and
/// core::Signal object.
/// @brief ABI and object conversion struct for signals. May be shared between processes.
struct SharedSignal {
amd_signal_t amd_signal;
Signal* core_signal;
Check<0x71FCCA6A3D5D5276, true> id;
bool IsValid() const { return id.IsValid(); }
SharedSignal() {
amd_signal.kind = AMD_SIGNAL_KIND_INVALID;
core_signal = nullptr;
}
static __forceinline SharedSignal* Convert(hsa_signal_t signal) {
if (signal.handle == 0) throw std::bad_cast();
SharedSignal* ret = reinterpret_cast<SharedSignal*>(static_cast<uintptr_t>(signal.handle) -
offsetof(SharedSignal, amd_signal));
if (!ret->IsValid()) throw std::bad_cast();
return ret;
}
};
static_assert(std::is_standard_layout<SharedSignal>::value,
"SharedSignal must remain standard layout for IPC use.");
static_assert(std::is_trivially_destructible<SharedSignal>::value,
"SharedSignal must not be modified on delete for IPC use.");
class LocalSignal {
public:
explicit LocalSignal(hsa_signal_value_t initial_value) {
if (!local_signal_.IsSharedObjectAllocationValid()) throw std::bad_alloc();
local_signal_.shared_object()->amd_signal.value = initial_value;
}
SharedSignal* signal() const { return local_signal_.shared_object(); }
private:
Shared<SharedSignal, AMD_SIGNAL_ALIGN_BYTES> local_signal_;
};
/// @brief An abstract base class which helps implement the public hsa_signal_t
/// type (an opaque handle) and its associated APIs. At its core, signal uses
/// a 32 or 64 bit value. This value can be waitied on or signaled atomically
/// using specified memory ordering semantics.
class Signal : public Checked<0x71FCCA6A3D5D5276>,
public Shared<SharedSignal, AMD_SIGNAL_ALIGN_BYTES> {
class Signal {
public:
/// @brief Constructor initializes the signal with initial value.
explicit Signal(hsa_signal_value_t initial_value)
: Shared(),
signal_(shared_object()->amd_signal),
async_copy_agent_(NULL) {
if (!Shared::IsSharedObjectAllocationValid()) {
invalid_ = true;
return;
}
/// @brief Constructor Links and publishes the signal interface object.
explicit Signal(SharedSignal* abi_block)
: signal_(abi_block->amd_signal), async_copy_agent_(NULL) {
if (abi_block == nullptr) throw std::bad_alloc();
shared_object()->core_signal = this;
signal_.kind = AMD_SIGNAL_KIND_INVALID;
signal_.value = initial_value;
invalid_ = false;
waiting_ = 0;
retained_ = 0;
abi_block->core_signal = this;
}
virtual ~Signal() { signal_.kind = AMD_SIGNAL_KIND_INVALID; }
virtual ~Signal() { invalid_ = true; }
bool IsValid() const {
if (CheckedType::IsValid() && !invalid_) return true;
return false;
}
bool IsValid() const { return !invalid_; }
/// @brief Converts from this implementation class to the public
/// hsa_signal_t type - an opaque handle.
static __forceinline hsa_signal_t Convert(Signal* signal) {
const uint64_t handle =
(signal != NULL && signal->IsValid())
? static_cast<uint64_t>(
reinterpret_cast<uintptr_t>(&signal->signal_))
: 0;
assert(signal != nullptr && signal->IsValid() && "Conversion on invalid Signal object.");
const uint64_t handle = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(&signal->signal_));
const hsa_signal_t signal_handle = {handle};
return signal_handle;
}
@@ -115,11 +134,8 @@ class Signal : public Checked<0x71FCCA6A3D5D5276>,
/// @brief Converts from this implementation class to the public
/// hsa_signal_t type - an opaque handle.
static __forceinline const hsa_signal_t Convert(const Signal* signal) {
const uint64_t handle =
(signal != NULL && signal->IsValid())
? static_cast<uint64_t>(
reinterpret_cast<uintptr_t>(&signal->signal_))
: 0;
assert(signal != nullptr && signal->IsValid() && "Conversion on invalid Signal object.");
const uint64_t handle = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(&signal->signal_));
const hsa_signal_t signal_handle = {handle};
return signal_handle;
}
@@ -127,13 +143,11 @@ class Signal : public Checked<0x71FCCA6A3D5D5276>,
/// @brief Converts from public hsa_signal_t type (an opaque handle) to
/// this implementation class object.
static __forceinline Signal* Convert(hsa_signal_t signal) {
return (signal.handle != 0)
? reinterpret_cast<const SharedSignal*>(
static_cast<uintptr_t>(signal.handle) -
(reinterpret_cast<uintptr_t>(
&reinterpret_cast<SharedSignal*>(1234)->amd_signal) -
uintptr_t(1234)))->core_signal
: NULL;
SharedSignal* shared = SharedSignal::Convert(signal);
if (shared->core_signal != nullptr)
return shared->core_signal;
else
throw std::bad_cast();
}
// Below are various methods corresponding to the APIs, which load/store the
@@ -77,18 +77,11 @@ volatile uint32_t AqlQueue::queue_count_ = 0;
KernelMutex AqlQueue::queue_lock_;
int AqlQueue::rtti_id_;
void* AqlQueue::operator new(size_t size) {
// Align base to 64B to enforce amd_queue_ member alignment.
return _aligned_malloc(size, kAmdQueueAlignBytes);
}
void AqlQueue::operator delete(void* ptr) { _aligned_free(ptr); }
AqlQueue::AqlQueue(GpuAgent* agent, size_t req_size_pkts, HSAuint32 node_id,
ScratchInfo& scratch, core::HsaEventCallback callback,
void* err_data, bool is_kv)
AqlQueue::AqlQueue(GpuAgent* agent, size_t req_size_pkts, HSAuint32 node_id, ScratchInfo& scratch,
core::HsaEventCallback callback, void* err_data, bool is_kv)
: Queue(),
Signal(0),
LocalSignal(0),
Signal(signal()),
ring_buf_(NULL),
ring_buf_alloc_bytes_(0),
queue_id_(HSA_QUEUEID(-1)),
@@ -48,7 +48,7 @@ namespace core {
int DefaultSignal::rtti_id_ = 0;
DefaultSignal::DefaultSignal(hsa_signal_value_t initial_value)
: Signal(initial_value) {
: LocalSignal(initial_value), Signal(signal()) {
signal_.kind = AMD_SIGNAL_KIND_USER;
signal_.event_mailbox_ptr = NULL;
HSA::hsa_memory_register(this, sizeof(DefaultSignal));
文件差异内容过多而无法显示 加载差异
@@ -40,6 +40,10 @@
//
////////////////////////////////////////////////////////////////////////////////
#include <new>
#include <typeinfo>
#include <exception>
#include "hsakmt.h"
#include "core/inc/runtime.h"
@@ -109,11 +113,37 @@ static __forceinline bool IsValid(T* ptr) {
return (ptr == NULL) ? NULL : ptr->IsValid();
}
#define TRY try {
#define CATCH } catch(...) { return AMD::handleException(); }
#define CATCHRET(RETURN_TYPE) } catch(...) { return AMD::handleExceptionT<RETURN_TYPE>(); }
namespace AMD {
hsa_status_t
hsa_amd_coherency_get_type(hsa_agent_t agent_handle,
hsa_amd_coherency_type_t* type) {
hsa_status_t handleException() {
try {
throw;
} catch (const std::bad_alloc& e) {
return HSA_STATUS_ERROR_OUT_OF_RESOURCES;
} catch (const std::bad_cast& e) {
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
} catch (std::nested_exception& e) { // Rethrow exceptions from callbacks after unwinding HSA.
e.rethrow_nested();
return HSA_STATUS_ERROR;
} catch (...) {
assert(false && "Unhandled exception.");
abort();
return HSA_STATUS_ERROR;
}
}
template <class T> static __forceinline T handleExceptionT() {
handleException();
abort();
return T();
}
hsa_status_t hsa_amd_coherency_get_type(hsa_agent_t agent_handle, hsa_amd_coherency_type_t* type) {
TRY
IS_OPEN();
const core::Agent* agent = core::Agent::Convert(agent_handle);
@@ -132,10 +162,12 @@ hsa_status_t
*type = gpu_agent->current_coherency_type();
return HSA_STATUS_SUCCESS;
CATCH
}
hsa_status_t hsa_amd_coherency_set_type(hsa_agent_t agent_handle,
hsa_amd_coherency_type_t type) {
hsa_amd_coherency_type_t type) {
TRY
IS_OPEN();
core::Agent* agent = core::Agent::Convert(agent_handle);
@@ -158,10 +190,11 @@ hsa_status_t hsa_amd_coherency_set_type(hsa_agent_t agent_handle,
}
return HSA_STATUS_SUCCESS;
CATCH
}
hsa_status_t
hsa_amd_memory_fill(void* ptr, uint32_t value, size_t count) {
hsa_status_t hsa_amd_memory_fill(void* ptr, uint32_t value, size_t count) {
TRY
IS_OPEN();
if (ptr == NULL) {
@@ -173,17 +206,15 @@ hsa_status_t
}
return core::Runtime::runtime_singleton_->FillMemory(ptr, value, count);
CATCH
}
hsa_status_t
hsa_amd_memory_async_copy(void* dst, hsa_agent_t dst_agent_handle,
const void* src, hsa_agent_t src_agent_handle,
size_t size, uint32_t num_dep_signals,
const hsa_signal_t* dep_signals,
hsa_signal_t completion_signal) {
if (dst == NULL || src == NULL) {
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
}
hsa_status_t hsa_amd_memory_async_copy(void* dst, hsa_agent_t dst_agent_handle, const void* src,
hsa_agent_t src_agent_handle, size_t size,
uint32_t num_dep_signals, const hsa_signal_t* dep_signals,
hsa_signal_t completion_signal) {
TRY
if (dst == NULL || src == NULL) { return HSA_STATUS_ERROR_INVALID_ARGUMENT; }
if ((num_dep_signals == 0 && dep_signals != NULL) ||
(num_dep_signals > 0 && dep_signals == NULL)) {
@@ -215,10 +246,11 @@ hsa_status_t
}
return HSA_STATUS_SUCCESS;
CATCH
}
hsa_status_t
hsa_amd_profiling_set_profiler_enabled(hsa_queue_t* queue, int enable) {
hsa_status_t hsa_amd_profiling_set_profiler_enabled(hsa_queue_t* queue, int enable) {
TRY
IS_OPEN();
core::Queue* cmd_queue = core::Queue::Convert(queue);
@@ -229,9 +261,11 @@ hsa_status_t
AMD_QUEUE_PROPERTIES_ENABLE_PROFILING, (enable != 0));
return HSA_STATUS_SUCCESS;
CATCH
}
hsa_status_t hsa_amd_profiling_async_copy_enable(bool enable) {
TRY
IS_OPEN();
return core::Runtime::runtime_singleton_->IterateAgent(
@@ -240,11 +274,13 @@ hsa_status_t hsa_amd_profiling_async_copy_enable(bool enable) {
return core::Agent::Convert(agent_handle)->profiling_enabled(enable);
},
reinterpret_cast<void*>(&enable));
CATCH
}
hsa_status_t hsa_amd_profiling_get_dispatch_time(
hsa_agent_t agent_handle, hsa_signal_t hsa_signal,
hsa_amd_profiling_dispatch_time_t* time) {
TRY
IS_OPEN();
IS_BAD_PTR(time);
@@ -267,10 +303,12 @@ hsa_status_t hsa_amd_profiling_get_dispatch_time(
gpu_agent->TranslateTime(signal, *time);
return HSA_STATUS_SUCCESS;
CATCH
}
hsa_status_t hsa_amd_profiling_get_async_copy_time(
hsa_signal_t hsa_signal, hsa_amd_profiling_async_copy_time_t* time) {
TRY
IS_OPEN();
IS_BAD_PTR(time);
@@ -295,12 +333,13 @@ hsa_status_t hsa_amd_profiling_get_async_copy_time(
time->start = signal->signal_.start_ts;
time->end = signal->signal_.end_ts;
return HSA_STATUS_SUCCESS;
CATCH
}
hsa_status_t
hsa_amd_profiling_convert_tick_to_system_domain(hsa_agent_t agent_handle,
uint64_t agent_tick,
uint64_t* system_tick) {
hsa_status_t hsa_amd_profiling_convert_tick_to_system_domain(hsa_agent_t agent_handle,
uint64_t agent_tick,
uint64_t* system_tick) {
TRY
IS_OPEN();
IS_BAD_PTR(system_tick);
@@ -318,31 +357,28 @@ hsa_status_t
*system_tick = gpu_agent->TranslateTime(agent_tick);
return HSA_STATUS_SUCCESS;
CATCH
}
uint32_t
hsa_amd_signal_wait_any(uint32_t signal_count, hsa_signal_t* hsa_signals,
hsa_signal_condition_t* conds,
hsa_signal_value_t* values, uint64_t timeout_hint,
hsa_wait_state_t wait_hint,
hsa_signal_value_t* satisfying_value) {
uint32_t hsa_amd_signal_wait_any(uint32_t signal_count, hsa_signal_t* hsa_signals,
hsa_signal_condition_t* conds, hsa_signal_value_t* values,
uint64_t timeout_hint, hsa_wait_state_t wait_hint,
hsa_signal_value_t* satisfying_value) {
TRY
// Do not check for signal invalidation. Invalidation may occur during async
// signal handler loop and is not an error.
for (uint i = 0; i < signal_count; i++)
assert(hsa_signals[i].handle != 0 &&
static_cast<core::Checked<0x71FCCA6A3D5D5276>*>(
core::Signal::Convert(hsa_signals[i]))->IsValid() &&
"Invalid signal.");
assert(core::SharedSignal::Convert(hsa_signals[i])->IsValid() && "Invalid signal.");
return core::Signal::WaitAny(signal_count, hsa_signals, conds, values,
timeout_hint, wait_hint, satisfying_value);
CATCHRET(uint32_t)
}
hsa_status_t
hsa_amd_signal_async_handler(hsa_signal_t hsa_signal,
hsa_signal_condition_t cond,
hsa_signal_value_t value,
hsa_amd_signal_handler handler, void* arg) {
hsa_status_t hsa_amd_signal_async_handler(hsa_signal_t hsa_signal, hsa_signal_condition_t cond,
hsa_signal_value_t value, hsa_amd_signal_handler handler,
void* arg) {
TRY
IS_OPEN();
core::Signal* signal = core::Signal::Convert(hsa_signal);
@@ -352,10 +388,11 @@ hsa_status_t
return HSA_STATUS_ERROR_INVALID_SIGNAL;
return core::Runtime::runtime_singleton_->SetAsyncSignalHandler(
hsa_signal, cond, value, handler, arg);
CATCH
}
hsa_status_t
hsa_amd_async_function(void (*callback)(void* arg), void* arg) {
hsa_status_t hsa_amd_async_function(void (*callback)(void* arg), void* arg) {
TRY
IS_OPEN();
IS_BAD_PTR(callback);
@@ -363,25 +400,28 @@ hsa_status_t
return core::Runtime::runtime_singleton_->SetAsyncSignalHandler(
null_signal, HSA_SIGNAL_CONDITION_EQ, 0, (hsa_amd_signal_handler)callback,
arg);
CATCH
}
hsa_status_t hsa_amd_queue_cu_set_mask(const hsa_queue_t* queue,
uint32_t num_cu_mask_count,
const uint32_t* cu_mask) {
TRY
IS_OPEN();
IS_BAD_PTR(cu_mask);
core::Queue* cmd_queue = core::Queue::Convert(queue);
IS_VALID(cmd_queue);
return cmd_queue->SetCUMasking(num_cu_mask_count, cu_mask);
CATCH
}
hsa_status_t hsa_amd_memory_lock(void* host_ptr, size_t size,
hsa_agent_t* agents, int num_agent,
void** agent_ptr) {
*agent_ptr = NULL;
hsa_agent_t* agents, int num_agent,
void** agent_ptr) {
TRY
IS_OPEN();
*agent_ptr = NULL;
if (size == 0 || host_ptr == NULL || agent_ptr == NULL) {
return HSA_STATUS_ERROR_INVALID_ARGUMENT;
@@ -397,9 +437,11 @@ hsa_status_t hsa_amd_memory_lock(void* host_ptr, size_t size,
core::Runtime::runtime_singleton_->system_regions_fine()[0]);
return system_region->Lock(num_agent, agents, host_ptr, size, agent_ptr);
CATCH
}
hsa_status_t hsa_amd_memory_unlock(void* host_ptr) {
TRY
IS_OPEN();
const amd::MemoryRegion* system_region =
@@ -407,12 +449,12 @@ hsa_status_t hsa_amd_memory_unlock(void* host_ptr) {
core::Runtime::runtime_singleton_->system_regions_fine()[0]);
return system_region->Unlock(host_ptr);
CATCH
}
hsa_status_t
hsa_amd_memory_pool_get_info(hsa_amd_memory_pool_t memory_pool,
hsa_amd_memory_pool_info_t attribute,
void* value) {
hsa_status_t hsa_amd_memory_pool_get_info(hsa_amd_memory_pool_t memory_pool,
hsa_amd_memory_pool_info_t attribute, void* value) {
TRY
IS_OPEN();
IS_BAD_PTR(value);
@@ -423,12 +465,14 @@ hsa_status_t
}
return mem_region->GetPoolInfo(attribute, value);
CATCH
}
hsa_status_t hsa_amd_agent_iterate_memory_pools(
hsa_agent_t agent_handle,
hsa_status_t (*callback)(hsa_amd_memory_pool_t memory_pool, void* data),
void* data) {
TRY
IS_OPEN();
IS_BAD_PTR(callback);
const core::Agent* agent = core::Agent::Convert(agent_handle);
@@ -446,11 +490,12 @@ hsa_status_t hsa_amd_agent_iterate_memory_pools(
reinterpret_cast<hsa_status_t (*)(hsa_region_t memory_pool, void* data)>(
callback),
data);
CATCH
}
hsa_status_t
hsa_amd_memory_pool_allocate(hsa_amd_memory_pool_t memory_pool, size_t size,
uint32_t flags, void** ptr) {
hsa_status_t hsa_amd_memory_pool_allocate(hsa_amd_memory_pool_t memory_pool, size_t size,
uint32_t flags, void** ptr) {
TRY
IS_OPEN();
if (size == 0 || ptr == NULL) {
@@ -466,15 +511,16 @@ hsa_status_t
return core::Runtime::runtime_singleton_->AllocateMemory(
mem_region, size, core::MemoryRegion::AllocateRestrict, ptr);
CATCH
}
hsa_status_t hsa_amd_memory_pool_free(void* ptr) {
return HSA::hsa_memory_free(ptr);
}
hsa_status_t
hsa_amd_agents_allow_access(uint32_t num_agents, const hsa_agent_t* agents,
const uint32_t* flags, const void* ptr) {
hsa_status_t hsa_amd_agents_allow_access(uint32_t num_agents, const hsa_agent_t* agents,
const uint32_t* flags, const void* ptr) {
TRY
IS_OPEN();
if (num_agents == 0 || agents == NULL || flags != NULL || ptr == NULL) {
@@ -483,12 +529,12 @@ hsa_status_t
return core::Runtime::runtime_singleton_->AllowAccess(num_agents, agents,
ptr);
CATCH
}
hsa_status_t
hsa_amd_memory_pool_can_migrate(hsa_amd_memory_pool_t src_memory_pool,
hsa_amd_memory_pool_t dst_memory_pool,
bool* result) {
hsa_status_t hsa_amd_memory_pool_can_migrate(hsa_amd_memory_pool_t src_memory_pool,
hsa_amd_memory_pool_t dst_memory_pool, bool* result) {
TRY
IS_OPEN();
if (result == NULL) {
@@ -512,11 +558,13 @@ hsa_status_t
}
return src_mem_region->CanMigrate(*dst_mem_region, *result);
CATCH
}
hsa_status_t hsa_amd_memory_migrate(const void* ptr,
hsa_amd_memory_pool_t memory_pool,
uint32_t flags) {
hsa_amd_memory_pool_t memory_pool,
uint32_t flags) {
TRY
IS_OPEN();
if (ptr == NULL || flags != 0) {
@@ -532,11 +580,13 @@ hsa_status_t hsa_amd_memory_migrate(const void* ptr,
}
return dst_mem_region->Migrate(flags, ptr);
CATCH
}
hsa_status_t hsa_amd_agent_memory_pool_get_info(
hsa_agent_t agent_handle, hsa_amd_memory_pool_t memory_pool,
hsa_amd_agent_memory_pool_info_t attribute, void* value) {
TRY
IS_OPEN();
if (value == NULL) {
@@ -555,6 +605,7 @@ hsa_status_t hsa_amd_agent_memory_pool_get_info(
}
return mem_region->GetAgentPoolInfo(*agent, attribute, value);
CATCH
}
hsa_status_t hsa_amd_interop_map_buffer(uint32_t num_agents,
@@ -563,6 +614,7 @@ hsa_status_t hsa_amd_interop_map_buffer(uint32_t num_agents,
void** ptr, size_t* metadata_size,
const void** metadata) {
static const int tinyArraySize=8;
TRY
IS_OPEN();
IS_BAD_PTR(agents);
IS_BAD_PTR(size);
@@ -589,39 +641,49 @@ hsa_status_t hsa_amd_interop_map_buffer(uint32_t num_agents,
if (num_agents > tinyArraySize) delete[] core_agents;
return ret;
CATCH
}
hsa_status_t hsa_amd_interop_unmap_buffer(void* ptr) {
TRY
IS_OPEN();
if (ptr != NULL) core::Runtime::runtime_singleton_->InteropUnmap(ptr);
return HSA_STATUS_SUCCESS;
CATCH
}
hsa_status_t hsa_amd_pointer_info(void* ptr, hsa_amd_pointer_info_t* info, void* (*alloc)(size_t),
uint32_t* num_accessible, hsa_agent_t** accessible) {
uint32_t* num_accessible, hsa_agent_t** accessible) {
TRY
IS_OPEN();
IS_BAD_PTR(ptr);
IS_BAD_PTR(info);
return core::Runtime::runtime_singleton_->PtrInfo(ptr, info, alloc, num_accessible, accessible);
CATCH
}
hsa_status_t hsa_amd_pointer_info_set_userdata(void* ptr, void* userdata) {
TRY
IS_OPEN();
IS_BAD_PTR(ptr);
return core::Runtime::runtime_singleton_->SetPtrInfoData(ptr, userdata);
CATCH
}
hsa_status_t hsa_amd_ipc_memory_create(void* ptr, size_t len, hsa_amd_ipc_memory_t* handle) {
TRY
IS_OPEN();
IS_BAD_PTR(ptr);
IS_BAD_PTR(handle);
return core::Runtime::runtime_singleton_->IPCCreate(ptr, len, handle);
CATCH
}
hsa_status_t hsa_amd_ipc_memory_attach(const hsa_amd_ipc_memory_t* ipc, size_t len,
uint32_t num_agents, const hsa_agent_t* mapping_agents,
void** mapped_ptr) {
static const int tinyArraySize = 8;
TRY
IS_OPEN();
IS_BAD_PTR(mapped_ptr);
if (num_agents != 0) IS_BAD_PTR(mapping_agents);
@@ -644,12 +706,15 @@ hsa_status_t hsa_amd_ipc_memory_attach(const hsa_amd_ipc_memory_t* ipc, size_t l
return core::Runtime::runtime_singleton_->IPCAttach(ipc, len, num_agents, core_agents,
mapped_ptr);
CATCH
}
hsa_status_t hsa_amd_ipc_memory_detach(void* mapped_ptr) {
TRY
IS_OPEN();
IS_BAD_PTR(mapped_ptr);
return core::Runtime::runtime_singleton_->IPCDetach(mapped_ptr);
CATCH
}
} // end of AMD namespace
@@ -68,9 +68,8 @@ int InterruptSignal::rtti_id_ = 0;
void InterruptSignal::DestroyEvent(HsaEvent* evt) { hsaKmtDestroyEvent(evt); }
InterruptSignal::InterruptSignal(hsa_signal_value_t initial_value,
HsaEvent* use_event)
: Signal(initial_value) {
InterruptSignal::InterruptSignal(hsa_signal_value_t initial_value, HsaEvent* use_event)
: LocalSignal(initial_value), Signal(signal()) {
if (use_event != NULL) {
event_ = use_event;
free_event_ = false;