return m2;
}
-#define MS_ALIGN_SIZE (16)
-#define MS_ALIGN(_x) (((_x) + (MS_ALIGN_SIZE-1)) & ~(MS_ALIGN_SIZE-1))
-
-/** Allocate an aligned pointer for packet (or struct data).
- *
- * This function is similar to fr_message_alloc() except that the
- * return value is aligned to CPU boundaries. The amount of data
- * allocated is also rounded up to the nearest alignment size.
- *
- * @param[in] ms the message set
- * @param[in] m the message message to allocate packet data for
- * @param[in] actual_packet_size to reserve
- * @return
- * - NULL on error
- * - fr_message_t* on success
- */
-fr_message_t *fr_message_alloc_aligned(fr_message_set_t *ms, fr_message_t *m, size_t actual_packet_size)
-{
- uint8_t *p, *aligned_p;
- intptr_t addr;
- size_t aligned_size;
-
-
- (void) talloc_get_type_abort(ms, fr_message_set_t);
-
- /* m is NOT talloc'd */
-
- /*
- * No existing message, try allocate enough room to align
- * both the start of the packet, and it's total size.
- */
- if (!m) {
- m = fr_message_reserve(ms, actual_packet_size + (2 * MS_ALIGN_SIZE) - 1);
- if (!m) return NULL;
- }
-
- fr_assert(m->status == FR_MESSAGE_USED);
- fr_assert(m->rb != NULL);
- fr_assert(m->data != NULL);
- fr_assert(m->data_size == 0);
- fr_assert(m->rb_size >= actual_packet_size);
-
- /*
- * Align the address and the actual packet size.
- */
- addr = (intptr_t) m->data;
- addr = MS_ALIGN(addr);
- aligned_p = (uint8_t *) addr;
-
- aligned_size = MS_ALIGN(actual_packet_size);
-
- if ((aligned_p + aligned_size) > (m->data + m->rb_size)) {
- fr_strerror_const("Aligned message size overflows reserved size");
- return NULL;
- }
-
- /*
- * The ring buffer has already allocated a possibly
- * un-aligned pointer. We wish to allocate enough room
- * to align both the pointer, and the structure size.
- */
- aligned_size = (aligned_p - m->data) + actual_packet_size;
- aligned_size = MS_ALIGN(aligned_size);
-
- p = fr_ring_buffer_alloc(m->rb, aligned_size);
- fr_assert(p != NULL);
- if (!p) {
- fr_strerror_const_push("Failed allocating from ring buffer");
- return NULL;
- }
-
- fr_assert(p == m->data);
- fr_assert((aligned_p + aligned_size) <= (m->data + m->rb_size));
-
- /*
- * Set the aligned pointer, the total aligned size, and
- * the structure size.
- */
- m->data = aligned_p;
- m->rb_size = aligned_size;
- m->data_size = actual_packet_size;
-
- return m;
-}
-
-
/** Count the number of used messages
*
* @param[in] ms the message set
fr_message_t *fr_message_alloc(fr_message_set_t *ms, fr_message_t *m, size_t actual_packet_size) CC_HINT(nonnull(1));
fr_message_t *fr_message_alloc_reserve(fr_message_set_t *ms, fr_message_t *m, size_t actual_packet_size,
size_t leftover, size_t reserve_size) CC_HINT(nonnull);
-fr_message_t *fr_message_alloc_aligned(fr_message_set_t *ms, fr_message_t *m, size_t actual_packet_size) CC_HINT(nonnull(1));
int fr_message_done(fr_message_t *m) CC_HINT(nonnull);
fr_message_t *fr_message_localize(TALLOC_CTX *ctx, fr_message_t *m, size_t message_size) CC_HINT(nonnull);
return NULL;
}
-
-/** Split an existing reservation into two.
- *
- * For protocols like TCP, there may sometimes be a partial packet at
- * the end of the ring buffer. We would like to pass a *complete*
- * packet around instead of a partial one. In that case, the partial
- * packet at the end of the buffer should be copied to a reservation
- * in a new ring buffer.
- *
- * i.e. the application uses fr_ring_buffer_reserve() to reserve 32K
- * of room. He then reads 32K of data into that buffer. This data
- * comprises 3 full packets of 10K, and one partial packet of 10K.
- * The application then calls fr_ring_buffer_alloc() three times, to
- * consume those packets. (Note that the caller doesn't really need
- * to do 3 calls to fr_ring_buffer_alloc(). The ring buffer does not
- * keep track of individual allocations).
- *
- * The application then calls fr_ring_buffer_reserve() to reserve
- * another 32K of room, while leaving 2K of data in the ring buffer.
- * If that reservation succeeds, great. Everything proceeds as
- * before. (Note that the application has to remember how much data
- * was in the ring buffer, and do it's reading there, instead of to
- * the pointer returned from fr_ring_buffer_reserve()).
- *
- * If that call fails, there is 2K of partial data in the buffer
- * which needs to be moved. The application should allocate a new
- * ring buffer, and then call this function to move the data to the
- * new ring buffer. The application then uses the new reservation to
- * read data.
- *
- * @param[in] dst ring buffer where the reservation will be made
- * @param[in] reserve_size size of the new reservation
- * @param[in] src ring buffer where the data is sitting.
- * @param[in] move_size of data to move from the tail of the buffer to the start.
- * @return
- * - NULL on error.
- * - pointer to data on success
- */
-uint8_t *fr_ring_buffer_reserve_split(fr_ring_buffer_t *dst, size_t reserve_size,
- fr_ring_buffer_t *src, size_t move_size)
-{
- uint8_t *p;
-
- (void) talloc_get_type_abort(src, fr_ring_buffer_t);
- (void) talloc_get_type_abort(dst, fr_ring_buffer_t);
-
- if (dst->closed) {
- fr_strerror_const("Allocation request after ring buffer is closed");
- return NULL;
- }
-
- /*
- * The application hasn't reserved enough space, so we can't
- * split the reservation.
- */
- if (src->reserved < move_size) {
- fr_strerror_const("Cannot move more data than was reserved.");
- return NULL;
- }
-
- /*
- * Create a new reservation.
- */
- p = fr_ring_buffer_reserve(dst, reserve_size);
- if (!p) return NULL;
-
- /*
- * Alloc and reserve in the same ring buffer. Maybe
- * there's no need to memcpy() the data?
- */
- if ((src == dst) && (p == (src->buffer + src->write_offset))) {
- return 0;
- }
-
- /*
- * Copy the data from the old buffer to the new one.
- */
- memcpy(p, src->buffer + src->write_offset, move_size);
-
- /*
- * We now have no data reserved here. All bets are
- * off...
- */
- src->reserved = 0;
-
- return p;
-}
-
-
/** Mark data as free,
*
* The size does not need to be a power of two. The application is
uint8_t *fr_ring_buffer_alloc(fr_ring_buffer_t *rb, size_t size);
-uint8_t *fr_ring_buffer_reserve_split(fr_ring_buffer_t *dst, size_t reserve_size,
- fr_ring_buffer_t *src, size_t move_size) CC_HINT(nonnull);
-
int fr_ring_buffer_start(fr_ring_buffer_t *dst, uint8_t **p_start, size_t *p_size);
int fr_ring_buffer_free(fr_ring_buffer_t *rb, size_t size) CC_HINT(nonnull);