fa772be675
## Overview and rationale This reverts https://github.com/ROCm/rocm-systems/pull/1886, which... * Re-applies https://github.com/ROCm/rocm-systems/pull/1866 * Reverts https://github.com/ROCm/rocm-systems/pull/1728 (So it restores the [`amdgpu-windows-interop/`](https://github.com/ROCm/rocm-systems/tree/develop/shared/amdgpu-windows-interop) folder back to the state from a few weeks ago) The rationale for this change is at https://github.com/ROCm/rocm-systems/pull/1866: > Last PAL update broke applications on gfx12 Windows. ## Cross-repository change details That PR failed to build but was merged with this explanation: > TheRock CI Windows build fails as expected with this revert. > > References to these PAL members need to be stripped out in a patch on TheRock. > > ``` > 11.3 C:\home\runner\_work\rocm-systems\rocm-systems\projects\clr\rocclr\device\pal\palubercapturemgr.cpp(152): error C2039: 'RegisterTraceStateChangeCallback': is not a member of 'GpuUtil::TraceSession' > 11.4 C:\home\runner\_work\rocm-systems\rocm-systems\shared\amdgpu-windows-interop\pal\inc\gpuUtil\palTraceSession.h(372): note: see declaration of 'GpuUtil::TraceSession' > 11.4 C:\home\runner\_work\rocm-systems\rocm-systems\projects\clr\rocclr\device\pal\palubercapturemgr.cpp(195): error C2039: 'UnregisterTraceStateChangeCallback': is not a member of 'GpuUtil::TraceSession' > 11.4 C:\home\runner\_work\rocm-systems\rocm-systems\shared\amdgpu-windows-interop\pal\inc\gpuUtil\palTraceSession.h(372): note: see declaration of 'GpuUtil::TraceSession' > ``` The patch in TheRock was updated in https://github.com/ROCm/TheRock/pull/2154. This rolls forward by updating the ref for TheRock. That original PR could have been sequenced differently to avoid a build break - perhaps by * Pointing to a branch in TheRock with the patch rebased * Deleting the patch in the workflows here but holding a local copy of the path to be applied in workflows * Landing the patch as a normal commit instead of carrying it at all ## Test plan 1. Watch TheRock CI here (https://github.com/ROCm/rocm-systems/actions/runs/19447202693/job/55644411119?pr=1893) 2. Build locally: ```bash # In rocm-systems git am --whitespace=nowarn D:\projects\TheRock\patches\amd-mainline\rocm-systems\0001-Revert-SWDEV-543498-Some-compute-Ubertrace-profiles-.patch git am --whitespace=nowarn D:\projects\TheRock\patches\amd-mainline\rocm-systems\0003-Use-is_versioned-true-consistently-in-both-Comgr-Loa.patch git am --whitespace=nowarn D:\projects\TheRock\patches\amd-mainline\rocm-systems\0006-Explicitly-load-libamdhip64.so.7.patch # Note: the build fails with the observed errors if patch 0001 is not applied! # In TheRock cmake -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_C_COMPILER=cl.exe -DCMAKE_CXX_COMPILER=cl.exe \ -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ -DPython3_EXECUTABLE=d:/projects/TheRock/.venv/Scripts/python \ -DTHEROCK_ROCM_SYSTEMS_SOURCE_DIR=d:/projects/TheRock/../rocm-systems \ # IMPORTANT -DTHEROCK_AMDGPU_FAMILIES=gfx110X-all \ -DBUILD_TESTING=ON \ -DTHEROCK_ENABLE_ALL=ON \ -Damd-llvm_BUILD_TYPE=RelWithDebInfo \ -S D:/projects/TheRock \ -B D:/projects/TheRock/build \ -G Ninja cmake --build D:/projects/TheRock/build --target hip-clr # [build] Build finished with exit code 0 cmake --build D:/projects/TheRock/build --target ocl-clr+dist # [build] Build finished with exit code 0 ```
294 lines
12 KiB
C++
294 lines
12 KiB
C++
/*
|
|
***********************************************************************************************************************
|
|
*
|
|
* Copyright (c) 2015-2025 Advanced Micro Devices, Inc. All Rights Reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
* copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*
|
|
**********************************************************************************************************************/
|
|
/**
|
|
***********************************************************************************************************************
|
|
* @file palIntrusiveList.h
|
|
* @brief PAL utility collection IntrusiveList and IntrusiveListIterator class declarations.
|
|
***********************************************************************************************************************
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "palUtil.h"
|
|
#include "palAssert.h"
|
|
|
|
namespace Util
|
|
{
|
|
|
|
// Forward declarations.
|
|
template<typename T> class IntrusiveList;
|
|
template<typename T> class IntrusiveListIterator;
|
|
|
|
/**
|
|
***********************************************************************************************************************
|
|
* @brief Encapsulates one node of an intrusive double-linked-list.
|
|
*
|
|
* A node is associated with one data pointer at construction. The data pointer cannot be changed and must be non-null.
|
|
*
|
|
* Note that InList() allows intrusive list users to verify if a given value has been stored in a list without iterating
|
|
* over the list provided that each node object has been designated for a particular list.
|
|
***********************************************************************************************************************
|
|
*/
|
|
template<typename T>
|
|
class IntrusiveListNode
|
|
{
|
|
public:
|
|
/// @param [in,out] pData Address of the data element which contains this intrusive node.
|
|
explicit IntrusiveListNode(T* pData);
|
|
|
|
/// Returns true if this node is present in an intrusive list.
|
|
bool InList() const;
|
|
|
|
private:
|
|
// This special constructor is provided for IntrusiveList's sentinel node which must have a null data pointer.
|
|
IntrusiveListNode();
|
|
|
|
T*const m_pData; // The data object that contains this node.
|
|
IntrusiveListNode<T>* m_pPrev; // Previous node in the list or null if this node is not in a list.
|
|
IntrusiveListNode<T>* m_pNext; // Next node in the list or null if this node is not in a list.
|
|
|
|
PAL_DISALLOW_COPY_AND_ASSIGN(IntrusiveListNode);
|
|
|
|
// Although this is a transgression of coding standards, it prevents IntrusiveListNode from requiring public
|
|
// accessor functions. The added encapsulation this provides is worthwhile.
|
|
friend class IntrusiveList<T>;
|
|
friend class IntrusiveListIterator<T>;
|
|
};
|
|
|
|
/**
|
|
***********************************************************************************************************************
|
|
* @brief Iterator for traversal of elements in a List collection.
|
|
*
|
|
* Allows traversal of all elements in a List going either forwards or backwards.
|
|
***********************************************************************************************************************
|
|
*/
|
|
template<typename T>
|
|
class IntrusiveListIterator
|
|
{
|
|
public:
|
|
~IntrusiveListIterator() { }
|
|
|
|
/// Returns true unless the iterator has advanced past the end of the list.
|
|
bool IsValid() const { return m_pCurrent != m_pSentinel; }
|
|
|
|
/// Returns a pointer to the current element. Returns null if the iterator is invalid.
|
|
T* Get() const { return m_pCurrent->m_pData; }
|
|
|
|
/// Advances the iterator to the previous position (move backward).
|
|
void Prev() { m_pCurrent = m_pCurrent->m_pPrev; }
|
|
|
|
/// Advances the iterator to the next position (move forward).
|
|
void Next() { m_pCurrent = m_pCurrent->m_pNext; }
|
|
|
|
/// Moves the iterator back to the start of the list.
|
|
void Restart() { m_pCurrent = m_pSentinel->m_pNext; }
|
|
|
|
private:
|
|
IntrusiveListIterator(const IntrusiveListNode<T>*const pSentinel, IntrusiveListNode<T>* pStart);
|
|
|
|
const IntrusiveListNode<T>*const m_pSentinel; // We need the sentinel to locate the list boundaries.
|
|
IntrusiveListNode<T>* m_pCurrent; // Pointer to the current node.
|
|
|
|
PAL_DISALLOW_DEFAULT_CTOR(IntrusiveListIterator);
|
|
|
|
// Although this is a transgression of coding standards, it means that List does not need to have a public interface
|
|
// specifically to implement this class. The added encapsulation this provides is worthwhile.
|
|
friend class IntrusiveList<T>;
|
|
};
|
|
|
|
/**
|
|
***********************************************************************************************************************
|
|
* @brief Templated, doubly-linked, intrusive, list container.
|
|
*
|
|
* This is meant for storing non-null pointers to elements of an arbitrary type using externally managed nodes.
|
|
* Operations which this class supports are:
|
|
*
|
|
* - Insertion at any point
|
|
* - Deletion at any point
|
|
* - Forwards and reverse iteration
|
|
*
|
|
* @warning This class is not thread-safe.
|
|
***********************************************************************************************************************
|
|
*/
|
|
template<typename T>
|
|
class IntrusiveList
|
|
{
|
|
public:
|
|
/// A convenient shorthand for IntrusiveListNode.
|
|
typedef IntrusiveListNode<T> Node;
|
|
|
|
/// A convenient shorthand for IntrusiveListIterator.
|
|
typedef IntrusiveListIterator<T> Iter;
|
|
|
|
IntrusiveList();
|
|
|
|
/// Returns the number of elements in the list, not counting the sentinel.
|
|
size_t NumElements() const { return m_numElements; }
|
|
|
|
/// Returns true if the list is empty.
|
|
bool IsEmpty() const { return m_sentinel.m_pNext == &m_sentinel; }
|
|
|
|
/// Returns an iterator pointing to the first element in the list. If the list is empty, the iterator starts out
|
|
/// pointing at the permanent sentinel node.
|
|
///
|
|
/// @returns An iterator pointing at the front end of the list.
|
|
Iter Begin() const { return Iter(&m_sentinel, m_sentinel.m_pNext); }
|
|
|
|
/// Returns an iterator pointing to the last element in the list. If the list is empty, the iterator starts out
|
|
/// pointing at the permanent sentinel node.
|
|
///
|
|
/// @returns An iterator pointing at the back end of the list.
|
|
Iter End() const { return Iter(&m_sentinel, m_sentinel.m_pPrev); }
|
|
|
|
/// Returns the data pointer at the front of the list.
|
|
///
|
|
/// @returns The data pointer at the front of the list or null if the list is empty.
|
|
T* Front() const { return m_sentinel.m_pNext->m_pData; }
|
|
|
|
/// Returns the data pointer at the back of the list.
|
|
///
|
|
/// @returns The data pointer at the back of the list or null if the list is empty.
|
|
T* Back() const { return m_sentinel.m_pPrev->m_pData; }
|
|
|
|
/// Pushes the specified node onto the front of the list.
|
|
///
|
|
/// @param [in] pNode Externally-owned list node to link into the list.
|
|
void PushFront(Node* pNode) { InsertBefore(m_sentinel.m_pNext, pNode); }
|
|
|
|
/// Pushes the specified node onto the back of the list.
|
|
///
|
|
/// @param [in] pNode Externally-owned list node to link into the list.
|
|
void PushBack(Node* pNode) { InsertBefore(&m_sentinel, pNode); }
|
|
|
|
/// Pushes the contents of pSource onto the front of this list. The ordering of pSource is preserved, meaning that
|
|
/// the front of pSource will be the new front of this list. Note that pSource will be left entirely empty.
|
|
///
|
|
/// It is illegal to call this function with an empty pSource.
|
|
///
|
|
/// @param [in] pSource The contents of pSource will be pushed in-order onto the front of this list.
|
|
void PushFrontList(IntrusiveList<T>* pSource);
|
|
|
|
/// Pushes the contents of pSource onto the back of this list. The ordering of pSource is preserved, meaning that
|
|
/// the end of pSource will be the new end of this list. Note that pSource will be left entirely empty.
|
|
///
|
|
/// It is illegal to call this function with an empty pSource.
|
|
///
|
|
/// @param [in] pSource The contents of pSource will be pushed in-order onto the back of this list.
|
|
void PushBackList(IntrusiveList<T>* pSource);
|
|
|
|
/// Inserts the specified node before a particular node in a list.
|
|
///
|
|
/// If the iterator has advanced off the end of the list (i.e., the iterator is invalid), the added node will be the
|
|
/// new tail node.
|
|
///
|
|
/// @param [in] iter Identifies a node where the insertion should take place. The iterator will point to the same
|
|
/// spot in the list after insertion.
|
|
/// @param [in] pNode Externally-owned list node to link into the list.
|
|
void InsertBefore(const Iter& iter, Node* pNode);
|
|
|
|
/// Removes the node at the specified position from the list.
|
|
///
|
|
/// It is illegal to call this function with an iterator that has already advanced off the end of the list.
|
|
///
|
|
/// @param [in,out] pIter Iterator identifying the node to be removed. After the node is removed, this iterator
|
|
/// will be advanced to the next node. If this call removes the final remaining node in the
|
|
/// list then the iterator will point at the sentinel and will be invalid.
|
|
void Erase(Iter* pIter);
|
|
|
|
/// Removes the node at the specified position from the list. It is illegal to call this function with a Node that
|
|
/// not in this list.
|
|
///
|
|
/// @param [in] pNode Node to be removed.
|
|
void Erase(Node* pNode);
|
|
|
|
/// Removes all nodes from the list.
|
|
void EraseAll();
|
|
|
|
/// Truncates the list without touching the elements
|
|
void InvalidateList()
|
|
{
|
|
m_sentinel.m_pNext = &m_sentinel;
|
|
m_sentinel.m_pPrev = &m_sentinel;
|
|
m_numElements = 0;
|
|
}
|
|
|
|
private:
|
|
void InsertBefore(Node* pBeforeMe, Node* pNode);
|
|
void Unlink(Node* pNode);
|
|
|
|
Node m_sentinel; // Ties the head to the tail and signifies the boundary of the list.
|
|
size_t m_numElements; // Number of elements.
|
|
|
|
PAL_DISALLOW_COPY_AND_ASSIGN(IntrusiveList);
|
|
};
|
|
|
|
// =====================================================================================================================
|
|
// This is the public node constructor; it must be given a non-null data pointer.
|
|
template<typename T>
|
|
IntrusiveListNode<T>::IntrusiveListNode(
|
|
T* pData)
|
|
:
|
|
m_pData(pData),
|
|
m_pPrev(nullptr),
|
|
m_pNext(nullptr)
|
|
{
|
|
PAL_ASSERT(pData != nullptr);
|
|
}
|
|
|
|
// =====================================================================================================================
|
|
// This is the private node constructor which is used exclusively for sentinel nodes.
|
|
template<typename T>
|
|
IntrusiveListNode<T>::IntrusiveListNode()
|
|
:
|
|
m_pData(nullptr),
|
|
m_pPrev(nullptr),
|
|
m_pNext(nullptr)
|
|
{
|
|
}
|
|
|
|
// =====================================================================================================================
|
|
// Returns true if this node is present in an intrusive list.
|
|
template<typename T>
|
|
bool IntrusiveListNode<T>::InList() const
|
|
{
|
|
// The node pointers should always be null or non-null together.
|
|
PAL_DEBUG_BUILD_ONLY_ASSERT((m_pPrev == nullptr) == (m_pNext == nullptr));
|
|
|
|
return (m_pNext != nullptr);
|
|
}
|
|
|
|
// =====================================================================================================================
|
|
template<typename T>
|
|
IntrusiveListIterator<T>::IntrusiveListIterator(
|
|
const IntrusiveListNode<T>*const pSentinel,
|
|
IntrusiveListNode<T>* pStart)
|
|
:
|
|
m_pSentinel(pSentinel),
|
|
m_pCurrent(pStart)
|
|
{
|
|
}
|
|
|
|
} // Util
|