Skip to content

[PATCH v3] api: event: add event type metadata to event vectors #2217

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 36 additions & 5 deletions include/odp/api/spec/event_vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,10 @@ void odp_event_vector_free(odp_event_vector_t evv);
* The event_tbl points to the event vector table. Application can edit the
* event handles in the table directly (up to odp_pool_param_t::event_vector.max_size).
* Application must update the size of the table using odp_event_vector_size_set()
* when there is a change in the size of the vector.
* when there is a change in the size of the vector. An application must also
* update the type of the event vector using odp_event_vector_type_set(), as
* necessary, after modifying the event vector and before passing the event
* vector to any ODP API function that takes a generic event parameter.
*
* Invalid event handles (ODP_EVENT_INVALID) are not allowed to be stored in the
* table to allow consumers of odp_event_vector_t handle to have optimized
Expand Down Expand Up @@ -119,26 +122,54 @@ uint32_t odp_event_vector_size(odp_event_vector_t evv);
/**
* Type of events stored in event vector
*
* If all events in the vector are of the same type, function returns the
* particular event type. If the vector is empty or includes multiple event
* types, ODP_EVENT_ANY is returned instead.
* Return the event type stored in event vector metadata. After event vector
* allocation the event type is ODP_EVENT_ANY. Event aggregators set the
* event type to the type of the events stored in the event vector or to
* ODP_EVENT_ANY if the vector contains events of multiple types or if the
* aggregator was not able to determine that all the event are of the same
* type. The event type can also be set through odp_event_vector_type_set().
*
* @param evv Event vector handle
*
* @return Event type
*/
odp_event_type_t odp_event_vector_type(odp_event_vector_t evv);

/**
* Set type of events stored in event vector
*
* The specified event type is stored in the event vector metadata and
* can be queried later through odp_event_vector_type(). The event type
* metadata does not need to match the actual type of events in the vector
* at all times but must be valid for the vector content (i.e. either
* ODP_EVENT_ANY or the same type as all events in the vector) when the
* event vector is passed to any ODP API function as a generic event
* (odp_event_t). API functions that take an event vector (odp_event_vector_t)
* parameter do not require a valid event vector type metadata.
*
* Calling odp_event_vector_type_set() is not necessary after modification
* of an event vector if the event type already has a valid value for the
* new content of the vector.
*
* @param evv Event vector handle
* @param type Event type
*/
void odp_event_vector_type_set(odp_event_vector_t evv, odp_event_type_t type);

/**
* Set the number of events stored in a vector
*
* Update the number of events stored in a vector. When the application is
* producing an event vector, this function shall be used by the application
* to set the number of events available in this vector.
*
* An application must update the type of the event vector using
* odp_event_vector_type_set(), as necessary, after modifying the event
* vector and before passing the event vector to any ODP API function.
*
* The maximum number of events this vector can hold is defined by
* odp_pool_param_t::event_vector.max_size. The size value must not be greater
* than odp_pool_param_t::event_vector.max_size
* than odp_pool_param_t::event_vector.max_size.
*
* All handles in the vector table (0 .. size - 1) need to be valid event
* handles.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ typedef struct _odp_event_vector_inline_offset_t {
uint16_t event;
uint16_t pool;
uint16_t size;
uint16_t event_type;
uint16_t uarea_addr;
uint16_t flags;

Expand Down
14 changes: 14 additions & 0 deletions platform/linux-generic/include/odp/api/plat/event_vector_inlines.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ extern "C" {
#define odp_event_vector_pool __odp_event_vector_pool
#define odp_event_vector_size __odp_event_vector_size
#define odp_event_vector_size_set __odp_event_vector_size_set
#define odp_event_vector_type __odp_event_vector_type
#define odp_event_vector_type_set __odp_event_vector_type_set
#define odp_event_vector_user_area __odp_event_vector_user_area
#define odp_event_vector_user_flag __odp_event_vector_user_flag
#define odp_event_vector_user_flag_set __odp_event_vector_user_flag_set
Expand Down Expand Up @@ -79,6 +81,18 @@ _ODP_INLINE void odp_event_vector_size_set(odp_event_vector_t evv, uint32_t size
*vector_size = size;
}

_ODP_INLINE odp_event_type_t odp_event_vector_type(odp_event_vector_t evv)
{
return _odp_event_vect_get(evv, odp_event_type_t, event_type);
}

_ODP_INLINE void odp_event_vector_type_set(odp_event_vector_t evv, odp_event_type_t type)
{
odp_event_type_t *evv_type = _odp_event_vect_get_ptr(evv, odp_event_type_t, event_type);

*evv_type = type;
}

_ODP_INLINE void *odp_event_vector_user_area(odp_event_vector_t evv)
{
return _odp_event_vect_get(evv, void *, uarea_addr);
Expand Down
22 changes: 17 additions & 5 deletions platform/linux-generic/include/odp_event_vector_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <odp/api/align.h>
#include <odp/api/debug.h>
#include <odp/api/packet.h>
#include <odp/api/buffer.h>
#include <odp/api/event_vector.h>

#include <odp/api/plat/event_vector_inline_types.h>
Expand All @@ -35,6 +36,9 @@ typedef struct ODP_ALIGNED_CACHE odp_event_vector_hdr_t {
/* Event vector size */
uint32_t size;

/* Common type of the events in the vector or ODP_EVENT_ANY */
odp_event_type_t event_type;

/* Flags */
_odp_event_vector_flags_t flags;

Expand Down Expand Up @@ -100,13 +104,21 @@ static inline void _odp_event_vector_free_full(odp_event_vector_t evv)
{
odp_event_vector_hdr_t *evv_hdr = _odp_event_vector_hdr(evv);

for (uint32_t i = 0; i < evv_hdr->size; i++)
for (uint32_t i = 0; i < evv_hdr->size; i++) {
_ODP_ASSERT(odp_event_type(evv_hdr->event[i]) != ODP_EVENT_VECTOR &&
odp_event_type(evv_hdr->event[i]) != ODP_EVENT_PACKET_VECTOR);

if (evv_hdr->size > 0)
odp_event_free_multi(evv_hdr->event, evv_hdr->size);

_ODP_ASSERT(evv_hdr->event_type == ODP_EVENT_ANY ||
evv_hdr->event_type == odp_event_type(evv_hdr->event[i]));
}

if (evv_hdr->size > 0) {
if (evv_hdr->event_type == ODP_EVENT_PACKET)
odp_packet_free_multi((odp_packet_t *)evv_hdr->event, evv_hdr->size);
else if (evv_hdr->event_type == ODP_EVENT_BUFFER)
odp_buffer_free_multi((odp_buffer_t *)evv_hdr->event, evv_hdr->size);
else
odp_event_free_multi(evv_hdr->event, evv_hdr->size);
}
odp_event_vector_free(evv);
}

Expand Down
22 changes: 3 additions & 19 deletions platform/linux-generic/odp_event_vector.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const _odp_event_vector_inline_offset_t _odp_event_vector_inline ODP_ALIGNED_CAC
.event = offsetof(odp_event_vector_hdr_t, event),
.pool = offsetof(odp_event_vector_hdr_t, event_hdr.pool),
.size = offsetof(odp_event_vector_hdr_t, size),
.event_type = offsetof(odp_event_vector_hdr_t, event_type),
.uarea_addr = offsetof(odp_event_vector_hdr_t, uarea_addr),
.flags = offsetof(odp_event_vector_hdr_t, flags)
};
Expand Down Expand Up @@ -51,6 +52,7 @@ odp_event_vector_t odp_event_vector_alloc(odp_pool_t pool_hdl)
return ODP_EVENT_VECTOR_INVALID;

_ODP_ASSERT(event_vector_hdr_from_event(event)->size == 0);
_ODP_ASSERT(event_vector_hdr_from_event(event)->event_type == ODP_EVENT_ANY);

return odp_event_vector_from_event(event);
}
Expand All @@ -61,29 +63,11 @@ void odp_event_vector_free(odp_event_vector_t evv)

evv_hdr->size = 0;
evv_hdr->flags.all_flags = 0;
evv_hdr->event_type = ODP_EVENT_ANY;

_odp_event_free(odp_event_vector_to_event(evv));
}

odp_event_type_t odp_event_vector_type(odp_event_vector_t evv)
{
odp_event_vector_hdr_t *evv_hdr = _odp_event_vector_hdr(evv);
uint32_t num = evv_hdr->size;
odp_event_type_t type;

if (odp_unlikely(num == 0))
return ODP_EVENT_ANY;

type = _odp_event_hdr(evv_hdr->event[0])->event_type;
for (uint32_t i = 1; i < num; i++) {
if (_odp_event_hdr(evv_hdr->event[i])->event_type != (int8_t)type) {
type = ODP_EVENT_ANY;
break;
}
}
return type;
}

void odp_event_vector_print(odp_event_vector_t evv)
{
int max_len = 4096;
Expand Down
70 changes: 24 additions & 46 deletions test/validation/api/event/event_vector.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,14 +139,14 @@ static void test_event_vector_print(void)

/*
* Test odp_event_vector_size{_set}(), odp_event_vector_tbl() and
* odp_event_vector_type() in several ways.
* odp_event_vector_type[_set}() in several ways.
*/
static void test_table_ops(void)
{
odp_pool_t pkt_pool;
odp_pool_t buf_pool;
odp_packet_t pkt;
odp_buffer_t buf, buf2;
odp_buffer_t buf;
odp_event_vector_t evv;
odp_event_t *ev_tbl, *ev_tbl2;
uint32_t size;
Expand All @@ -155,11 +155,9 @@ static void test_table_ops(void)
pkt = odp_packet_alloc(pkt_pool, PKT_LEN);
CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID);

buf_pool = create_buffer_pool(2);
buf_pool = create_buffer_pool(1);
buf = odp_buffer_alloc(buf_pool);
CU_ASSERT_FATAL(buf != ODP_BUFFER_INVALID);
buf2 = odp_buffer_alloc(buf_pool);
CU_ASSERT_FATAL(buf2 != ODP_BUFFER_INVALID);

evv = odp_event_vector_alloc(evv_pool);
CU_ASSERT_FATAL(evv != ODP_EVENT_VECTOR_INVALID);
Expand All @@ -171,65 +169,41 @@ static void test_table_ops(void)
CU_ASSERT(size == 0);
CU_ASSERT(ev_tbl != NULL);

/* put one packet handle in the vector */
/* must be able to set event type of an empty vector */
odp_event_vector_type_set(evv, ODP_EVENT_BUFFER);
CU_ASSERT(odp_event_vector_type(evv) == ODP_EVENT_BUFFER);

/* put packet handle in the vector */
ev_tbl[0] = odp_packet_to_event(pkt);
odp_event_vector_size_set(evv, 1);
/* tbl[] == {packet} */
CU_ASSERT(odp_event_vector_size(evv) == 1);
CU_ASSERT(odp_event_vector_type(evv) == ODP_EVENT_PACKET);
size = odp_event_vector_tbl(evv, &ev_tbl2);
CU_ASSERT(size == 1);
CU_ASSERT(ev_tbl == ev_tbl2);

/* change the packet handle to a buffer handle */
ev_tbl[0] = odp_buffer_to_event(buf);
/* tbl[] == {buffer} */
CU_ASSERT(odp_event_vector_size(evv) == 1);
CU_ASSERT(odp_event_vector_type(evv) == ODP_EVENT_BUFFER);
size = odp_event_vector_tbl(evv, &ev_tbl2);
CU_ASSERT(size == 1);
CU_ASSERT(ev_tbl == ev_tbl2);
odp_event_vector_type_set(evv, ODP_EVENT_PACKET);
CU_ASSERT(odp_event_vector_type(evv) == ODP_EVENT_PACKET);

/* append a packet handle in the vector */
ev_tbl[1] = odp_packet_to_event(pkt);
/* add a buffer in the vector */
ev_tbl[1] = odp_buffer_to_event(buf);
odp_event_vector_size_set(evv, 2);
/* tbl[] == {buffer, packet} */
CU_ASSERT(odp_event_vector_size(evv) == 2);
CU_ASSERT(odp_event_vector_type(evv) == ODP_EVENT_ANY);
size = odp_event_vector_tbl(evv, &ev_tbl2);
CU_ASSERT(size == 2);
CU_ASSERT(ev_tbl == ev_tbl2);

/* change the packet handle to a buffer handle */
ev_tbl[1] = odp_buffer_to_event(buf2);
/* tbl[] == {buffer, buffer} */
CU_ASSERT(odp_event_vector_size(evv) == 2);
CU_ASSERT(odp_event_vector_type(evv) == ODP_EVENT_BUFFER);
size = odp_event_vector_tbl(evv, &ev_tbl2);
CU_ASSERT(size == 2);
CU_ASSERT(ev_tbl == ev_tbl2);

/* change first handle to packet and truncate */
ev_tbl[0] = odp_packet_to_event(pkt);
odp_event_vector_size_set(evv, 1);
/* tbl[] == {packet} */
CU_ASSERT(odp_event_vector_type(evv) == ODP_EVENT_PACKET);
size = odp_event_vector_tbl(evv, &ev_tbl2);
CU_ASSERT(size == 1);
CU_ASSERT(ev_tbl == ev_tbl2);
odp_event_vector_type_set(evv, ODP_EVENT_ANY);
CU_ASSERT(odp_event_vector_type(evv) == ODP_EVENT_ANY);

/* truncate to zero length */
odp_event_vector_type_set(evv, ODP_EVENT_PACKET);
odp_event_vector_size_set(evv, 0);
/* tbl[] == {} */
CU_ASSERT(odp_event_vector_type(evv) == ODP_EVENT_ANY);
CU_ASSERT(odp_event_vector_type(evv) == ODP_EVENT_PACKET);
size = odp_event_vector_tbl(evv, &ev_tbl2);
CU_ASSERT(size == 0);
CU_ASSERT(ev_tbl == ev_tbl2);

odp_event_vector_free(evv);
odp_packet_free(pkt);
odp_buffer_free(buf);
odp_buffer_free(buf2);

CU_ASSERT(odp_pool_destroy(pkt_pool) == 0);
CU_ASSERT(odp_pool_destroy(buf_pool) == 0);
Expand Down Expand Up @@ -302,8 +276,7 @@ static void test_content_freeing(void)
evv = alloc_and_fill_vector(ev, num_bufs);
size = odp_event_vector_tbl(evv, &ev_tbl);
CU_ASSERT(size == num_bufs);
ev_tbl[num_bufs] = odp_packet_to_event(pkt); /* no size increment yet */
CU_ASSERT(odp_event_vector_type(evv) == ODP_EVENT_BUFFER);
ev_tbl[num_bufs] = odp_packet_to_event(pkt);
odp_event_vector_size_set(evv, num_bufs + 1);
CU_ASSERT(odp_event_vector_type(evv) == ODP_EVENT_ANY);

Expand Down Expand Up @@ -368,8 +341,7 @@ static void test_vector_freeing(void)

/*
* Test that two event vectors allocated from the same pool have
* different handles, user areas (if supported), user flags, sizes
* and event tables.
* different handles, user areas (if supported) and metadata.
*/
static void test_uniqueness(void)
{
Expand Down Expand Up @@ -405,6 +377,12 @@ static void test_uniqueness(void)
CU_ASSERT(odp_event_vector_size(evv2) == 0);
odp_event_vector_size_set(evv1, 0);

CU_ASSERT(odp_event_vector_type(evv1) == ODP_EVENT_ANY);
CU_ASSERT(odp_event_vector_type(evv2) == ODP_EVENT_ANY);
odp_event_vector_type_set(evv1, ODP_EVENT_PACKET);
CU_ASSERT(odp_event_vector_type(evv1) == ODP_EVENT_PACKET);
CU_ASSERT(odp_event_vector_type(evv2) == ODP_EVENT_ANY);

odp_event_vector_free(evv1);
odp_event_vector_free(evv2);
}
Expand Down