Bill Fischofer(Bill-Fischofer-Linaro) replied on github web page:

platform/linux-generic/odp_queue.c
@@ -471,51 +476,18 @@ static inline int deq_multi(queue_entry_t *queue, 
odp_buffer_hdr_t *buf_hdr[],
                }
 
                UNLOCK(&queue->s.lock);
-               return 0;
-       }
-
-       for (i = 0; i < num && hdr; ) {
-               int burst_num = hdr->burst_num;
-               int first     = hdr->burst_first;
 
-               /* First, get bursted buffers */
-               for (j = 0; j < burst_num && i < num; j++, i++) {
-                       buf_hdr[i] = hdr->burst[first + j];
-                       odp_prefetch(buf_hdr[i]);
-               }
-
-               if (burst_num) {
-                       hdr->burst_num   = burst_num - j;
-                       hdr->burst_first = first + j;
-               }
-
-               if (i == num)
-                       break;
-
-               /* When burst is empty, consume the current buffer header and
-                * move to the next header */
-               buf_hdr[i] = hdr;
-               next       = hdr->next;
-               hdr->next  = NULL;
-               hdr        = next;
-               updated++;
-               i++;
+               return 0;
        }
 
-       /* Write head only if updated */
-       if (updated)
-               queue->s.head = hdr;
-
-       /* Queue is empty */
-       if (hdr == NULL)
-               queue->s.tail = NULL;
-
        if (status_sync && queue->s.type == ODP_QUEUE_TYPE_SCHED)
                sched_fn->save_context(queue->s.index);
 
        UNLOCK(&queue->s.lock);
 
-       return i;
+       buffer_index_to_buf(buf_hdr, buf_idx, num_deq);


Comment:
Given its name, this looks like an extraneous statement that should be deleted. 
Renaming this to something like `prefetch_dequeued_bufs()` would make the 
intent clearer here.

> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
> `if (!ring_st_is_empty(&queue->s.ring_st))` seems more natural here.


>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>> Change to `if (param->size >= CONFIG_QUEUE_SIZE)` to handle the effective 
>> queue capacity. The user-supplied `size` should then be set to 
>> `ROUNDUP_POWER2_U32(size) - 1` for the masking to work properly.


>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>> Same comment here as for plain queues.


>>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>>> As noted earlier, due to "losing" one entry to distinguish queue 
>>>> empty/full, this should be returned as `CONFIG_QUEUE_SIZE - 1`, and we 
>>>> also need to ensure that `CONFIG_QUEUE_SIZE` is itself a power of 2.


>>>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>>>> Since you're initializing `index.pool` and `index.buffer` there's no need 
>>>>> to set `index.u32` here.


>>>>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>>>>> We originally had this index partitioning based on `ODP_CONFIG_POOLS`. 
>>>>>> Do we want to return to that here?
>>>>>> 
>>>>>> If not, we at least need an `ODP_STATIC_ASSERT()` to ensure that 
>>>>>> `ODP_CONFIG_POOLS < 256` or else bad things will happen here.


>>>>>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>>>>>> This routine can be optimized to:
>>>>>>> ```
>>>>>>> return ring->head == ring->tail;
>>>>>>> ```


>>>>>>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>>>>>>> Your invariant is the queue is empty when `head == tail` therefore the 
>>>>>>>> queue is full when `abs(tail - head) == mask`, so the correct 
>>>>>>>> calculation here is:
>>>>>>>> 
>>>>>>>> `num = mask - abs(tail - head);`
>>>>>>>> 
>>>>>>>> The effect is that a queue can only hold `size - 1` elements, 
>>>>>>>> otherwise you cannot distinguish between a full and an empty queue 
>>>>>>>> without another bit of metadata, which is a cost you're trying to 
>>>>>>>> avoid.
>>>>>>>> 
>>>>>>>> This is somewhat problematic if the caller is trying to be "optimal" 
>>>>>>>> by specifying a power of two in the `size` parameter of the 
>>>>>>>> `odp_queue_param_t` passed to `odp_queue_create()`. For this reason we 
>>>>>>>> may wish to return a `max_size` of a power of 2 - 1 in 
>>>>>>>> `odp_queue_capability()` as part of this patch series.


>>>>>>>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>>>>>>>> This only works if `size` is a power of 2. Should be documented as 
>>>>>>>>> such, since this is an internal routine. In this case an 
>>>>>>>>> `ODP_ASSERT(size == ROUNDUP_POWER2_U32(size))` for this requirement 
>>>>>>>>> would be a useful debugging aid.


>>>>>>>>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>>>>>>>>> should be `num = abs(tail - head);` to deal with wrap arounds, 
>>>>>>>>>> otherwise may be misinterpreted as overly large since it's 
>>>>>>>>>> `uint32_t`. Note that GCC and clang recognize `abs()` and treat it 
>>>>>>>>>> as a builtin, so there's no actual `stdlib.h` call here.


>>>>>>>>>>> Bill Fischofer(Bill-Fischofer-Linaro) wrote:
>>>>>>>>>>> Extra blank line should be removed (nit).


https://github.com/Linaro/odp/pull/492#discussion_r169824164
updated_at 2018-02-22 09:32:40

Reply via email to