odp_buffer_t buffer_alloc(void *pool, size_t size) { struct pool_entry_s *pool_s = &((pool_entry_t *)pool)->s; uintmax_t totsize = size + pool_s->room_size; odp_buffer_hdr_t *buf; /* Reject oversized allocation requests */ if (odp_unlikely(size > pool_s->max_size)) return ODP_BUFFER_INVALID; /* Try to satisfy request from the local cache */ buf = get_local_buf(&pool_s->local_cache[local_id], pool_s, totsize); /* If cache is empty, satisfy request from the pool */ if (odp_unlikely(buf == NULL)) { buf = get_buf(pool_s); if (odp_unlikely(buf == NULL)) return ODP_BUFFER_INVALID; /* Get blocks for this buffer, if pool uses application data */ if (buf->size < totsize) { intmax_t needed = totsize - buf->size; do { uint8_t *blk = get_blk(pool_s); if (blk == NULL) { ret_buf(pool_s, buf); return ODP_BUFFER_INVALID; } buf->addr[buf->segcount++] = blk; needed -= pool_s->seg_size; } while (needed > 0); buf->size = buf->segcount * pool_s->seg_size; /* Record the hdr before the buffer head */ *(unsigned long *)(buf->addr[0] - ODP_HDR_BACK_PTR_SIZE) = (unsigned long)buf; } } /* Mark buffer as allocated */ buf->allocator = local_id; /* By default, buffers inherit their pool's zeroization setting */ buf->flags.zeroized = pool_s->flags.zeroized; /* By default, buffers are not associated with an ordered queue */ buf->origin_qe = NULL; return (odp_buffer_t)buf; }
odp_buffer_t buffer_alloc(odp_pool_t pool_hdl, size_t size) { uint32_t pool_id = pool_handle_to_index(pool_hdl); pool_entry_t *pool = get_pool_entry(pool_id); uintmax_t totsize = pool->s.headroom + size + pool->s.tailroom; odp_anybuf_t *buf; /* Reject oversized allocation requests */ if ((pool->s.flags.unsegmented && totsize > pool->s.seg_size) || (!pool->s.flags.unsegmented && totsize > pool->s.seg_size * ODP_BUFFER_MAX_SEG)) return ODP_BUFFER_INVALID; /* Try to satisfy request from the local cache */ buf = (odp_anybuf_t *)(void *)get_local_buf(&local_cache[pool_id], &pool->s, totsize); /* If cache is empty, satisfy request from the pool */ if (odp_unlikely(buf == NULL)) { buf = (odp_anybuf_t *)(void *)get_buf(&pool->s); if (odp_unlikely(buf == NULL)) return ODP_BUFFER_INVALID; /* Get blocks for this buffer, if pool uses application data */ if (buf->buf.size < totsize) { intmax_t needed = totsize - buf->buf.size; do { uint8_t *blk = get_blk(&pool->s); if (blk == NULL) { ret_buf(&pool->s, &buf->buf); return ODP_BUFFER_INVALID; } buf->buf.addr[buf->buf.segcount++] = blk; needed -= pool->s.seg_size; } while (needed > 0); buf->buf.size = buf->buf.segcount * pool->s.seg_size; } } /* By default, buffers inherit their pool's zeroization setting */ buf->buf.flags.zeroized = pool->s.flags.zeroized; if (buf->buf.type == ODP_EVENT_PACKET) packet_init(pool, &buf->pkt, size); return odp_hdr_to_buf(&buf->buf); }