dpa_u_a_bo_any_t | The BO can refer to any kind of data, and can have any valid tag |
---|---|
dpa_u_a_bo_gc_t | The BO can contain unique, refcounted and static data |
dpa_u_a_bo_unique_t | This tagged BO pointer has an unique value. Data smaller than 8 bytes will be inlined. Unused bytes will be 0. |
enum dpa_u_bo_type_flags | |
---|---|
DPA_U_BO_SIMPLE | If this tag is set, the pointer points to a dpa_u_bo_t object. Except for inlined data, this is always the case. |
DPA_U_BO_STATIC | The data has static lifetime. The data will never be freed. The BO object may not have static lifetime though. |
DPA_U_BO_REFCOUNTED | The data has a reference count. This is never an inline BO. The BO object itself is not refcounted. |
DPA_U_BO_UNIQUE |
The data of this BO is unique. The BO itself is refcounted. The BO and it's data are immutable, they
will not change. The data may or may not have it's own refcount, and it may or may not store it's hash, and this may change depending on the data and between implementations. |
DPA_U_BO_HASHED | The BO is pre-hashed. |
All dpa_u_a_bo_* objects represent either tagged BO pointers, or inlined data.
Inlined data can be at most 7 bytes big. The first byte is reserved for the tag of the tagged BO pointer. The tag
contains information about the type of object it points to, and the lifetime of the data the BO refers to,
but the lifetime of the BO object itself may differ from that. The tag also contains the length of inline data
if it is an inline BO.
If a tagged BO pointer is dereferenced, the resulting BO object will be const qualified.
A tagged BO pointer without any tags represents an error value. An error value is an inline BO object which is not marked as unique. In other words, it can be safely dereferenced, and then contains the name of the error. However, it is recommended to actually check if a tagged BO pointer is an error object, using the dpa_u_bo_is_error function.
Currently, only the simple dpa_u_bo_t type is implemented.
There are internal types for hashed and refcounted BOs, but there are no plans to expose them as of now.
This is because there is no way to define a hashed refcounted bo in such a way that a pointer to it can be
converted to both, a hashed bo and a refcounted bo, without type-punning, which would be UB.
There are tagged pointers for hashed and refcounted BOs, and functions for creating them in the current block
scope, as well as functions for getting the refcount and the hash.
Type | Name | Description |
---|---|---|
size | The size of the BO. | |
data | A pointer to the data |
The lifetime of BO objects may be shorter than that of the data. The only exception are inline BOs.
The lifetime of an inline BO always matches that of the tagged BO pointer value itself.
Special care must be taken when passing a refcounted BO which is not a unique BO to another function, or when
storing it in a shared object. In that case only the data is refcounted, and multiple refcounted BO objects
referencing the same data with shorter lifetimes could exist. Unlike with unique BOs, incrementing the refcount
is insufficient in this case, BO objects of sufficient lifetime must be created.
A BO pointer tagged as static has statically allocated data, but the BO may not be statically allocated.
This is similar to refcounted BOs.
When storing, for example, a dpa_u_a_bo_gc_t in a shared object, when it is not known if the BO has a sufficient lifetime, a new BO Object needs to be allocated. The functions dpa_u_bo_copy_maybe and dpa_u_bo_copy_bo_maybe exist to help with that.
As a convention, functions will assume that the BOs tagged pointers point to, and their data, are immutable. They may store them under that assumption. However, this doesn't always have to be the case. If the BO or it's data is not immutable, it may be necessarey to copy it in that case. The function dpa_u_bo_needs_copy can be used to force a BO to be copied later if necessary.
If the BO is a unique BO, this function just increments the BOs refcount. Otherwise a new BO object is allocated. The refcount of the data of a refcounted BO is also incremented, in addition to a new BO object being allocated. If a BO is neither unique, nor refcounted, nor static, the data is also copied.
Unlike dpa_u_bo_copy_maybe, this function does not copy the BOs data. Everything else is the same. Only use this function if the data is known to have a sufficient lifetime.
If it is a unique BO, only the unique BOs refcount is incremented. Otherwise the datas refcount is incremented. If there is no refcount, nothing happens. This function is thread safe.
If it is a unique BO, only the unique BOs refcount is decremented. Otherwise the datas refcount is decremented. If the refcount hits 0, the data is freed. If it is a unique BO, the unique BO is removed from the set of unique BOs, and the refcount of the data is decremented if there is one, and freed once nothing references it anymore. This function is thread safe.
Takes a tagged BO pointer. If it is an error object, returns true. Otherwise, it returns false.
Takes an errno value, returns a dpa_u_a_bo_unique_t. The BO object will not be a unique bo, though, but an error object.
Takes an error object. If it corrensponds to a known errno value, that value is returned. Otherwiese, -1 is returned.
Returns true if the BOs are the same object. If it's a tagged pointer, the pointer without the tags are compared. If it's a BO object, it is referenced and the resulting pointer is compared.
Returns true if the BOs have the same size & data, false otherwise.
Returns 0 if the BOs have the same size & data. Returns a positive or negative value otherwise. If both BOs are unique BOs, only the pointers are compared. Otherwise, the size and data is compared. This function can be used for sorting BOs, so long as unique and non-unique BOs are not mixed. If there are unique and non-unique BOs, use dpa_u_bo_compare_data instead.
Returns 0 if the BOs have the same size & data. Returns a positive or negative value otherwise. Can be used for sorting. It first compares the size, then the data using memcmp, that is the order qa sort is going to have.
Interns a BO. Returns a unique BO. If the data is refcounted or static, it may not copy it, but just increment the refcount instead. When passing a refcounted BO to this function, make sure it's data is immutable. To force the data to be copied, use the dpa_u_bo_untag_gc function. This function is thread safe.
Returns an lvalue reference to the BO.
Returns a dpa_u_a_bo_any_t to the specified BO.
Returns a dpa_u_a_bo_any_t to the specified BO. It is tagged as a static BO.
Returns a dpa_u_a_bo_gc_t to the specified BO. If the conversion isn't allowed at runtime, an error object will be returned. The BO to be converted must be refcounted, static, inline, unique, or a combination of those things.
Takes a dpa_u_bo_t. Returns a dpa_u_a_bo_gc_t to the specified BO. It is tagged as a static BO.
Takes a dpa_u_bo_t and a pointer to a dpa_u_refcount_freeable_t. Creates a new BO object in the current block scope with a pointer to a refcount. If the refcount is static, the BO pointer is tagged as static. Returns a dpa_u_a_bo_any_t*.
Takes a dpa_u_bo_t and a uint64_t containing the hash. The hash must be the same as would have been calculated using the dpa_u_bo_get_hash function. Creates a new BO object in the current block scope with a hash. Returns a dpa_u_a_bo_any_t*.
Takes a dpa_u_bo_t and a uint64_t containing the hash. The hash must be the same as would have been calculated using the dpa_u_bo_get_hash function. Creates a new BO object in the current block scope with a hash. The tagged BO pointer has the static flag set. Returns a dpa_u_a_bo_any_t*.
Takes a dpa_u_bo_t, a pointer to a dpa_u_refcount_freeable_t and a uint64_t containing the hash. The hash must be the same as would have been calculated using the dpa_u_bo_get_hash function. Creates a new BO object in the current block scope with a pointer to a refcount and a hash. If the refcount is static, the BO pointer is tagged as static. Returns a dpa_u_a_bo_any_t*.
Takes a dpa_u_bo_t and a pointer to a dpa_u_refcount_freeable_t. Creates a new BO object in the current block scope with a pointer to a refcount. If the refcount is static, the BO pointer is tagged as static. Returns a dpa_u_a_bo_gc_t*.
Takes a dpa_u_bo_t and a uint64_t containing the hash. The hash must be the same as would have been calculated using the dpa_u_bo_get_hash function. Creates a new BO object in the current block scope with a hash. The tagged BO pointer has the static flag set. Returns a dpa_u_a_bo_gc_t*.
Takes a dpa_u_bo_t, a pointer to a dpa_u_refcount_freeable_t and a uint64_t containing the hash. The hash must be the same as would have been calculated using the dpa_u_bo_get_hash function. Creates a new BO object in the current block scope with a pointer to a refcount and a hash. If the refcount is static, the BO pointer is tagged as static. Returns a dpa_u_a_bo_gc_t*.
Takes a dpa_u_bo_t and a pointer to a dpa_u_refcount_freeable_t. Allocates a new BO with a pointer to a refcount. If the refcount is static, the BO pointer is tagged as static. This BO must be freed later using dpa_u_bo_free. Returns a dpa_u_a_bo_any_t*.
Takes a dpa_u_bo_t and a uint64_t containing the hash. The hash must be the same as would have been calculated using the dpa_u_bo_get_hash function. Allocates a new BO with a hash. This BO must be freed later using dpa_u_bo_free. Returns a dpa_u_a_bo_any_t*.
Takes a dpa_u_bo_t and a uint64_t containing the hash. The hash must be the same as would have been calculated using the dpa_u_bo_get_hash function. Allocates a new BO with a hash. This BO must be freed later using dpa_u_bo_free. The tagged BO pointer has the static flag set. Returns a dpa_u_a_bo_any_t*.
Takes a dpa_u_bo_t, a pointer to a dpa_u_refcount_freeable_t and a uint64_t containing the hash. The hash must be the same as would have been calculated using the dpa_u_bo_get_hash function. Allocates a new BO with a pointer to a refcount and a hash. If the refcount is static, the BO pointer is tagged as static. This BO must be freed later using dpa_u_bo_free. Returns a dpa_u_a_bo_any_t*.
Takes a dpa_u_bo_t and a pointer to a dpa_u_refcount_freeable_t. Allocates a new BO with a pointer to a refcount. If the refcount is static, the BO pointer is tagged as static. This BO must be freed later using dpa_u_bo_free. Returns a dpa_u_a_bo_gc_t*.
Takes a dpa_u_bo_t and a uint64_t containing the hash. The hash must be the same as would have been calculated using the dpa_u_bo_get_hash function. Allocates a new BO with a hash. This BO must be freed later using dpa_u_bo_free. The tagged BO pointer has the static flag set. Returns a dpa_u_a_bo_gc_t*.
Takes a dpa_u_bo_t, a pointer to a dpa_u_refcount_freeable_t and a uint64_t containing the hash. The hash must be the same as would have been calculated using the dpa_u_bo_get_hash function. Allocates a new BO with a pointer to a refcount and a hash. If the refcount is static, the BO pointer is tagged as static. This BO must be freed later using dpa_u_bo_free. Returns a dpa_u_a_bo_gc_t*.
Takes a dpa_u_a_bo_unique_t, returns a uint64_t. This uint64_t can be turned back into a dpa_u_a_bo_unique_t using dpa_u_bo_unique_from_uint. Think of it as casting the tagged pointer to a uint64_t. Although, the tagged BO pointers are actually implemented using a uint64_t, so nothing is really converted.
This turns a uint64_t back into a dpa_u_a_bo_unique_t. This is the reverse of the dpa_u_bo_unique_to_uint function.
In case of a dpa_u_a_bo_unique_t, this does nothing, the same pointer is returned. Otherwise, it removes refcounted and static BO pointer tags, and returns a dpa_u_a_bo_any_t tag. This is useful if the BO may change later, but the function it is passed to may store it but shouldn't be affected by the changes to the BO. Removing these tags forces the BO to be copied in that case if necessary.
Returns a pointer to the BOs data.
Get the size of the BO.
Get the hash of the BO. If the BO doesn't have a hash pre-calculated, it calculates the hash.
Returns a pointer to a dpa_u_refcount_freeable_t. If it is a unique BO, this is the refcount of the BO object. Otherwise, it is only the refcount of the data. Returns 0 if there is no refcount, including if there is a unique BO.