CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
176 lines
8.2 KiB
C++
176 lines
8.2 KiB
C++
// WARNING: Changes to this file must be contributed back to Sawyer or else they will
|
|
// be clobbered by the next update from Sawyer. The Sawyer repository is at
|
|
// https://github.com/matzke1/sawyer.
|
|
|
|
|
|
|
|
|
|
#ifndef Sawyer_AddressSegment_H
|
|
#define Sawyer_AddressSegment_H
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <string>
|
|
#include <dyncompat/cstdint.hpp>
|
|
#include "Access.h"
|
|
#include "AllocatingBuffer.h"
|
|
#include "MappedBuffer.h"
|
|
#include "NullBuffer.h"
|
|
#include "StaticBuffer.h"
|
|
#include "Sawyer.h"
|
|
|
|
namespace Sawyer {
|
|
namespace Container {
|
|
|
|
/** A homogeneous interval of an address space.
|
|
*
|
|
* A segment imparts access permissions and other address-map related characteristics to a buffer. The segment represents one
|
|
* contiguous, homogeneous interval of an address space and thus points to one buffer that implements the value-storage for
|
|
* that part of the address space.
|
|
*
|
|
* A segment doesn't store information about where it's mapped in an address space since that's the responsibility of the map
|
|
* containing the segment. A segment points to a buffer which might not be the same size as what is entered in the map;
|
|
* buffers that are longer than the mapped interval of address space have data which is not accessible (at least not through
|
|
* that segment), and buffers that are shorter may return short data from read and write operations. */
|
|
template<class A = size_t, class T = uint8_t>
|
|
class AddressSegment {
|
|
typename Buffer<A, T>::Ptr buffer_; // reference counted buffer
|
|
A offset_; // initial offset into buffer
|
|
unsigned accessibility_; // uninterpreted bit mask
|
|
std::string name_; // for debugging
|
|
|
|
public:
|
|
typedef A Address; /**< Address types expected to be used by the underlying buffer. */
|
|
typedef T Value; /**< Type of values stored by the underlying buffer. */
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------
|
|
// Constructors
|
|
//-------------------------------------------------------------------------------------------------------------------
|
|
public:
|
|
|
|
/** Default constructor.
|
|
*
|
|
* Constructs a segment that does not point to any buffer. This is mainly to fulfill the requirement that values in an
|
|
* IntervalMap are default constructable. */
|
|
AddressSegment(): offset_(0), accessibility_(0) {}
|
|
|
|
/** Copy constructor.
|
|
*
|
|
* Creates a new segment that's an exact copy of @p other. Both segments will point to the same underlying buffer, which
|
|
* is reference counted. */
|
|
AddressSegment(const AddressSegment &other)
|
|
: buffer_(other.buffer_), offset_(other.offset_), accessibility_(other.accessibility_), name_(other.name_) {}
|
|
|
|
/** Construct a segment with buffer.
|
|
*
|
|
* This is the usual way that segments are created: by specifying a buffer and some access permissions. */
|
|
explicit AddressSegment(const typename Buffer<Address, Value>::Ptr &buffer, Address offset=0, unsigned accessBits=0,
|
|
const std::string &name="")
|
|
: buffer_(buffer), offset_(offset), accessibility_(accessBits), name_(name) {}
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------
|
|
// The following static methods are convenience wrappers around various buffer types.
|
|
//-------------------------------------------------------------------------------------------------------------------
|
|
public:
|
|
|
|
/** Create a segment that points to no data.
|
|
*
|
|
* Creates a segment of the specified size that points to a NullBuffer. This creates a segment which returns default
|
|
* constructed values when read, which fails when written. Such a segment is appropriate and efficient for mapping very
|
|
* large areas of an address space. */
|
|
static AddressSegment nullInstance(Address size, unsigned accessBits=0, const std::string &name="") {
|
|
return AddressSegment(NullBuffer<A, T>::instance(size), 0, accessBits, name);
|
|
}
|
|
|
|
/** Create a segment with no backing store.
|
|
*
|
|
* Creates a segment by allocating default-constructed values. Writes to this segment will update the underlying buffer,
|
|
* but the buffer is only stored in memory and not attached to any type of file or permanent storage. */
|
|
static AddressSegment anonymousInstance(Address size, unsigned accessBits=0, const std::string &name="") {
|
|
return AddressSegment(AllocatingBuffer<A, T>::instance(size), 0, accessBits, name);
|
|
}
|
|
|
|
/** Create a segment that points to a static buffer.
|
|
*
|
|
* Ownership of the buffer is not transferred to the segment.
|
|
*
|
|
* @{ */
|
|
static AddressSegment staticInstance(Value *buffer, Address size, unsigned accessBits=0, const std::string &name="") {
|
|
return AddressSegment(StaticBuffer<A, T>::instance(buffer, size), 0, accessBits, name);
|
|
}
|
|
static AddressSegment staticInstance(const Value *buffer, Address size, unsigned accessBits=0, const std::string &name="") {
|
|
return AddressSegment(StaticBuffer<A, T>::instance(buffer, size), 0, accessBits|Access::IMMUTABLE, name);
|
|
}
|
|
/** @} */
|
|
|
|
/** Map a file into an address space. */
|
|
static AddressSegment fileInstance(const std::string &fileName, unsigned accessBits=Access::READABLE,
|
|
const std::string &name="") {
|
|
int mode = (accessBits & Access::WRITABLE)!=0 ?
|
|
1 :
|
|
0;
|
|
return AddressSegment(MappedBuffer<A, T>::instance(fileName, mode), 0, accessBits, name);
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------
|
|
// Properties
|
|
//-------------------------------------------------------------------------------------------------------------------
|
|
public:
|
|
/** Property: buffer.
|
|
*
|
|
* This is the @ref Buffer object that represents the values stored in this interval of the address space. The first
|
|
* value in this segment, no matter where or if it's mapped in an address-mapping container, corresponds to the value
|
|
* stored at address zero of the buffer.
|
|
*
|
|
* @{ */
|
|
typename Buffer<A, T>::Ptr buffer() const { return buffer_; }
|
|
AddressSegment& buffer(const typename Buffer<A, T>::Ptr &b) { buffer_ = b; return *this; }
|
|
/** @} */
|
|
|
|
/** Property: buffer offset.
|
|
*
|
|
* The offset into the buffer corresponding to the first value of this segment.
|
|
*
|
|
* @{ */
|
|
A offset() const { return offset_; }
|
|
AddressSegment& offset(A n) { offset_ = n; return *this; }
|
|
/** @} */
|
|
|
|
/** Property: access rights.
|
|
*
|
|
* This property stores access rights as an unsigned integer. It makes no interpretation of what the various bits mean
|
|
* since the meaning is imparted by the mapping container.
|
|
*
|
|
* @{ */
|
|
unsigned accessibility() const { return accessibility_; }
|
|
AddressSegment& accessibility(unsigned bits) { accessibility_ = bits; return *this; }
|
|
/** @} */
|
|
|
|
/** Property: name.
|
|
*
|
|
* Each segment may be given a name which can be used for debugging.
|
|
*
|
|
* @{ */
|
|
const std::string &name() const { return name_; }
|
|
AddressSegment& name(const std::string &s) { name_ = s; return *this; }
|
|
/** @} */
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------
|
|
// Other methods
|
|
//-------------------------------------------------------------------------------------------------------------------
|
|
public:
|
|
/** Determines whether this segment is accessible.
|
|
*
|
|
* Returns true if all bits that are set in @p requiredAccess are also set in this segment, and none of the bits set in @p
|
|
* prohibitedAccess are set in this segment. */
|
|
bool isAccessible(unsigned requiredAccess, unsigned prohibitedAccess) const {
|
|
return requiredAccess==(accessibility_ & requiredAccess) && 0==(accessibility_ & prohibitedAccess);
|
|
}
|
|
|
|
};
|
|
|
|
} // namespace
|
|
} // namespace
|
|
|
|
#endif
|