ppisa commented on PR #17283:
URL: https://github.com/apache/nuttx/pull/17283#issuecomment-3492820981

   After some parallel discussion there is some alternative approach.
   
   Instead of the read buffer fill size, when the more messages are not 
transferred into read buffer, there is another may it be more valuable option 
to specify alignment of read "slots". If the alignment is size of the the whole 
maximal message and the buffer size is the same then the result is the same as 
for above option. But if there is interest to minimize syscalls count, then it 
is possible to offer buffer size in read equal to size of multiple full 
messages. But there is even another usage which has not been thought yet 
probably, and it is specifying of the messages alignment required for correct 
read of ext ID and other header fields. Because on the architetures hich do not 
support unaligned reads actual code requires memcopy of the second and followup 
messages to some other corretly aligned location to not experience unaligned 
fault. Even or some RISC-V, i.e. PolarFire where ABI guarantees unaligned 
accesses, the unaligned reads are emulated by SBI and are extremely slow.
   
   So the suggestion is to change the control IOTL to `CANIOC_SET_MSGALIGN` and 
then ensure, that next message is placed into read buffer at location 
controlled by align. There is problem that power of two alignments have purpose 
for these cases where only aliment  is intended but when whole message buffer 
is required it is (header size + data size + optional pad to ensure next header 
alignment). The required elements alignment is automatically ensured when 
sizeof(struct ...) is used... So there is proposal for processing of alignment 
which minimizes high divide cost operations. The `a` is specified alignment, 
`s` is size of the header plus data and `n` is span between current filed 
message and next message to put into buffer
   
   ```
   if (a & (a -1)) { /* alignment is not power of two */
     if (s <= a) {
       n = a;
     } else {
       n = s + a - 1;
       n = n - (n % a);
     }
   } else { /* easy case, power of two */
     n = a - 1;
     n = (s + n) & ~n;
   }
   ```
   This setup seems to me as the most practically usable, but suggestions and 
alternatives are welcomed.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to