changeset 273:b35d175b130e

issue: https://bugs.openjdk.java.net/browse/DIO-20 Summary: i/o via SPI is completely broken. Reviewed-by:snazarki Contributed-by:bkvartsk
author onazarkina
date Thu, 24 Mar 2016 12:20:34 +0300
parents 04fedde14532
children 935bcaf28721
files src/share/classes/com/oracle/dio/spibus/impl/SPICompositeMessageImpl.java
diffstat 1 files changed, 65 insertions(+), 67 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/oracle/dio/spibus/impl/SPICompositeMessageImpl.java	Mon Mar 21 17:21:43 2016 +0300
+++ b/src/share/classes/com/oracle/dio/spibus/impl/SPICompositeMessageImpl.java	Thu Mar 24 12:20:34 2016 +0300
@@ -24,16 +24,16 @@
  */
 
 package com.oracle.dio.spibus.impl;
+
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 
 import com.oracle.dio.utils.ExceptionMessage;
+
 import java.io.InterruptedIOException;
 import java.nio.BufferOverflowException;
 import java.util.ConcurrentModificationException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 
 import jdk.dio.ClosedDeviceException;
 import jdk.dio.UnavailableDeviceException;
@@ -59,6 +59,7 @@
     private class Message {
         ByteBuffer tx, rx, newTx, newRx;
         int skip, delay;
+
         public Message(ByteBuffer tx, int skip, ByteBuffer rx, int delay) {
             this.rx = rx;
             this.skip = skip;
@@ -70,7 +71,7 @@
     private void checkStatus() throws ClosedDeviceException {
         if (isAlreadyTransferedOnce) {
             throw new IllegalStateException(
-                ExceptionMessage.format(ExceptionMessage.I2CBUS_ALREADY_TRANSFERRED_MESSAGE)
+                    ExceptionMessage.format(ExceptionMessage.I2CBUS_ALREADY_TRANSFERRED_MESSAGE)
             );
         }
         if (!device.isOpen()) {
@@ -84,19 +85,19 @@
 
         if (0 > message.skip) {
             throw new IllegalArgumentException(
-                ExceptionMessage.format(ExceptionMessage.I2CBUS_NEGATIVE_SKIP_ARG)
+                    ExceptionMessage.format(ExceptionMessage.I2CBUS_NEGATIVE_SKIP_ARG)
             );
         }
 
         for (int i = 0; i < messageList.size(); i++) {
             ByteBuffer tx = messageList.get(i).tx;
             ByteBuffer rx = messageList.get(i).rx;
-            if (    (null != tx && (tx == message.tx ||
-                                    tx == message.rx) )
-                 || (null != rx && (rx == message.tx ||
-                                    rx == message.rx ) ) ) {
+            if ((null != tx && (tx == message.tx ||
+                    tx == message.rx))
+                    || (null != rx && (rx == message.tx ||
+                    rx == message.rx))) {
                 throw new IllegalArgumentException(
-                    ExceptionMessage.format(ExceptionMessage.I2CBUS_BUFFER_GIVEN_TWICE)
+                        ExceptionMessage.format(ExceptionMessage.I2CBUS_BUFFER_GIVEN_TWICE)
                 );
             }
         }
@@ -114,7 +115,7 @@
     }
 
     @Override
-    public SPICompositeMessage appendRead(ByteBuffer rxBuf)  throws IOException, ClosedDeviceException {
+    public SPICompositeMessage appendRead(ByteBuffer rxBuf) throws IOException, ClosedDeviceException {
         return appendRead(0, rxBuf);
     }
 
@@ -126,7 +127,7 @@
     }
 
     @Override
-    public SPICompositeMessage appendWrite( ByteBuffer txBuf) throws IOException,
+    public SPICompositeMessage appendWrite(ByteBuffer txBuf) throws IOException,
             ClosedDeviceException {
         //null check
         txBuf.limit();
@@ -139,14 +140,14 @@
     }
 
     @Override
-    public SPICompositeMessage appendWriteAndRead(ByteBuffer src, int skip, ByteBuffer dst) throws IOException, ClosedDeviceException{
+    public SPICompositeMessage appendWriteAndRead(ByteBuffer src, int skip, ByteBuffer dst) throws IOException, ClosedDeviceException {
         //null check
         src.limit();
         dst.limit();
-        return append(src,skip,dst);
+        return append(src, skip, dst);
     }
 
-    private synchronized SPICompositeMessage append(ByteBuffer src, int skip, ByteBuffer dst)  throws IOException, ClosedDeviceException {
+    private synchronized SPICompositeMessage append(ByteBuffer src, int skip, ByteBuffer dst) throws IOException, ClosedDeviceException {
         Message message = new Message(src, skip, dst, delay);
         check(message);
         messageList.add(message);
@@ -166,33 +167,30 @@
     public SPIDevice getTargetedDevice() {
         return device;
     }
-    
+
     /**
-     * Returns buffers are suitable for low level SPI operations 
+     * Returns buffers are suitable for low level SPI operations
      * New src buffer is located at index 0, dst buffer is at index 1
      * The both buffers are direct to avoid native resource allocations in low levels
      * The both buffers are the same length
      *
-     * @param originalSrc 
-     *            original array to be sent
-     * @param originalDst 
-     *            The buffer into which bytes are to be transferred
-     *
+     * @param originalSrc original array to be sent
+     * @param originalDst The buffer into which bytes are to be transferred
      * @return New buffers in the array. newSrcBuf = array[0], newDstBuf = array[1]
-     */    
+     */
     private ByteBuffer[] getBuffersForTransfer(ByteBuffer originalSrc, int skip, ByteBuffer originalDst) {
         int bytesInSrc = originalSrc == null ? 0 : originalSrc.remaining();
         int bytesInDst = originalDst == null ? 0 : originalDst.remaining();
-                
+
         int newRequiredSizeOfBuffers = bytesInSrc < (skip + bytesInDst) ?
-                                            skip + bytesInDst :
-                                            bytesInSrc;
-        
+                skip + bytesInDst :
+                bytesInSrc;
+
         ByteBuffer[] array = new ByteBuffer[2];
-        
-        if(originalSrc == null || !originalSrc.isDirect() || originalSrc.remaining() < newRequiredSizeOfBuffers) {
+
+        if (originalSrc == null || !originalSrc.isDirect() || originalSrc.remaining() < newRequiredSizeOfBuffers) {
             array[0] = (ByteBuffer) ByteBuffer.allocateDirect(newRequiredSizeOfBuffers);
-            if(originalSrc != null) {
+            if (originalSrc != null) {
                 array[0].put(originalSrc);
             }
             array[0].rewind();
@@ -201,15 +199,15 @@
             //after calling read/write/append operations
             array[0] = originalSrc.slice();
         }
-        
-        if(originalDst == null || !originalDst.isDirect() || originalDst.remaining() < newRequiredSizeOfBuffers) {
+
+        if (originalDst == null || !originalDst.isDirect() || originalDst.remaining() < newRequiredSizeOfBuffers) {
             array[1] = ByteBuffer.allocateDirect(newRequiredSizeOfBuffers);
         } else {
             //Can not use originalDst as is, because caller code can change position and limit
             //after calling read/write/append operations
             array[1] = originalDst.slice();
         }
-        
+
         return array;
     }
 
@@ -224,61 +222,61 @@
             }
 
             device.beginTransaction();
-            
+
             try {
                 final int size = messageList.size();
-                int[] bytesRead = new int[rxMsgs];
                 for (int i = 0; i < size; i++) {
                     Message message = messageList.get(i);
                     ByteBuffer[] newBuffers = getBuffersForTransfer(message.tx, message.skip, message.rx);
                     message.newTx = newBuffers[0];
                     message.newRx = newBuffers[1];
-                    
+
                     //New buffers have the same length and to avoid a dummy native call
                     //just make tranfers of non-empty buffers
-                    if(message.newRx.remaining() > 0) {
+                    if (message.newRx.remaining() > 0) {
                         device.transferWithLock(message.newTx, message.newRx);
                     }
-                    
+
                     Thread.currentThread().sleep((message.delay / 1000), (message.delay % 1000) * 1000);
                 }
-                
-                device.endTransaction();
-                int j = 0;
-                for(Message message : messageList) {
-                    if(message.tx != null) {
-                        message.tx.position(message.tx.limit());
-                    }
-                    
-                    if(message.rx != null) {
-                        message.newRx.position(message.skip);
-                        try {
-                            message.newRx.limit(message.skip + message.rx.remaining());
 
-                            bytesRead[j++] = message.newRx.remaining();
-                        
-                            message.rx.put(message.newRx);
-                        } catch(BufferOverflowException | IllegalArgumentException ex) {
-                            //IAE for newRx.limit and BOE is for rx.put
-                            throw new ConcurrentModificationException(
-                                ExceptionMessage.format(
-                                        ExceptionMessage.SPIBUS_BYTE_BUFFER_MODIFICATION));
-                                    
-                        }
-                    }
-                    
-                    message.newRx = null;
-                    message.newTx = null;
-                }
-                
-                return bytesRead;
-            
             } catch (InterruptedException ex) {
                 throw new InterruptedIOException(ExceptionMessage.format(
                         ExceptionMessage.SPIBUS_TRANSFER_INTERRUPTED));
             } finally {
                 device.endTransaction();
             }
+
+            int j = 0;
+            int[] bytesRead = new int[rxMsgs];
+
+            for (Message message : messageList) {
+                if (message.tx != null) {
+                    message.tx.position(message.tx.limit());
+                }
+
+                if (message.rx != null) {
+                    message.newRx.position(message.skip);
+                    try {
+                        message.newRx.limit(message.skip + message.rx.remaining());
+
+                        bytesRead[j++] = message.newRx.remaining();
+
+                        message.rx.put(message.newRx);
+                    } catch (BufferOverflowException | IllegalArgumentException ex) {
+                        //IAE for newRx.limit and BOE is for rx.put
+                        throw new ConcurrentModificationException(
+                                ExceptionMessage.format(
+                                        ExceptionMessage.SPIBUS_BYTE_BUFFER_MODIFICATION));
+
+                    }
+                }
+
+                message.newRx = null;
+                message.newTx = null;
+            }
+
+            return bytesRead;
         }
     }
 }