>>
>> Thinking again of what differentiate poll/select versus blocking  
>> read/write (as it was implemented in our code): say we have a  
>> fragment of 100 frames and we want to run/process with a buffer  
>> size of 256 frames :
>>
>> Reasoning at input side "only" for now:
>
> Looking at "half" the question is inadequate, because while you're  
> blocking for read (for example), the write side can underflow. You  
> need to be able to process either read *or* write, when they become  
> available.
>
>>
>> 1) poll/select would wake up the application as soon as a first 100  
>> frames fragment is available at input? Then the application can  
>> read 100 frames without blocking, then the application suspends,  
>> the second 100 frames fragment wakes up the application... read 100  
>> frames again, ... until we have at least 256 frames (so 3  
>> fragments) then the 256 frames input buffer can be processed....  
>> and so on
>>
>> 2) the application tries to read a full 256 frames buffer, the read  
>> returns as soon as enough frames are available in the drivers so,  
>> here also when 3 fragments have been "internally" received?
>>
>> So what are the fundamental difference here?
>
> For a non-duplex operation, there isn't much difference. (Although  
> you might occasionally have more or less than 100 frames available  
> at a time. So you have to check before you transfer the data, or use  
> a non-blocking read, in case 1, otherwise it can degenerate into  
> case 2.
>
> -- Garrett
>>

Ok, now the duplex case: in our model we *require* that the same  
number of frames (here 256) is given to the Process part at each  
cycle. Thus we need to "wait" at least 3 fragments to start processing  
(in either poll or "blocking 256 frames" read). Obviously if the  
application waits in the "blocking 256 frames" read, the write side  
may underflow. So we need to prefill the output side one complete 256  
frames buffer (at least) *before* starting the Read/Process/Write loop  
to avoid that situation.

But then if we do :

- prefill the output side with one complete 256 frames buffer

- enter Read/Process/Write loop

we are supposed to be in a case where output always has a buffer  
available, that is for a given cycle, we can *safely* read the 256  
frames input buffer, Process our 256 frames buffer and then write it.  
If for some reason the Process takes too much time, then we have an  
Xrun, but this make sense.

As I understand the poll/select model, the application has to read  
data and reconstruct itself the 256 frames input buffer (of write the  
256 output buffer by "slices"). On the contrary the blocking 256  
frames Read/Process/Write model let the driver does this job, and just  
has to prepare (that is write) the first output buffer. But then the  
Read/Process/Write is simpler and avoid some uneeded kernel/userland  
switches.

Does this make sense?

Stephane Letz



Reply via email to