Index: frysk-core/frysk/proc/Breakpoint.java =================================================================== RCS file: /cvs/frysk/frysk-core/frysk/proc/Breakpoint.java,v retrieving revision 1.14 diff -u -r1.14 Breakpoint.java --- frysk-core/frysk/proc/Breakpoint.java 20 Jul 2007 11:36:06 -0000 1.14 +++ frysk-core/frysk/proc/Breakpoint.java 2 Aug 2007 10:48:33 -0000 @@ -138,7 +138,7 @@ */ private void set(Task task) { - ByteBuffer buffer = task.getMemory(); + ByteBuffer buffer = task.getRawMemory(); Isa isa = task.getIsa(); Instruction bpInstruction = isa.getBreakpointInstruction(); @@ -147,8 +147,7 @@ // Put in the breakpoint. byte[] bs = bpInstruction.getBytes(); buffer.position(address); - for (int index = 0; index < bs.length; index++) - buffer.putByte(bs[index]); + buffer.put(bs); } /** @@ -174,7 +173,7 @@ */ private void reset(Task task) { - ByteBuffer buffer = task.getMemory(); + ByteBuffer buffer = task.getRawMemory(); buffer.position(address); Isa isa = task.getIsa(); @@ -185,8 +184,7 @@ // Only need to put back the part of the original instruction // covered by the breakpoint instruction bytes. - for (int index = 0; index < bp.length; index++) - buffer.putByte(bs[index]); + buffer.put(bs, 0, bp.length); } /** Index: frysk-core/frysk/proc/BreakpointAddresses.java =================================================================== RCS file: /cvs/frysk/frysk-core/frysk/proc/BreakpointAddresses.java,v retrieving revision 1.7 diff -u -r1.7 BreakpointAddresses.java --- frysk-core/frysk/proc/BreakpointAddresses.java 20 Jul 2007 11:36:06 -0000 1.7 +++ frysk-core/frysk/proc/BreakpointAddresses.java 2 Aug 2007 10:48:33 -0000 @@ -79,7 +79,7 @@ /** * Package private constructor used by the Proc when created. */ - BreakpointAddresses(Proc proc) + public BreakpointAddresses(Proc proc) { this.proc = proc; map = new HashMap(); Index: frysk-core/frysk/proc/Instruction.java =================================================================== RCS file: /cvs/frysk/frysk-core/frysk/proc/Instruction.java,v retrieving revision 1.2 diff -u -r1.2 Instruction.java --- frysk-core/frysk/proc/Instruction.java 2 Jul 2007 10:05:18 -0000 1.2 +++ frysk-core/frysk/proc/Instruction.java 2 Aug 2007 10:48:33 -0000 @@ -140,10 +140,9 @@ */ public void setupExecuteOutOfLine(Task task, long pc, long address) { - ByteBuffer buffer = task.getMemory(); + ByteBuffer buffer = task.getRawMemory(); buffer.position(address); - for (int i = 0; i < instr.length; i++) - buffer.putByte(instr[i]); + buffer.put(instr); task.getIsa().setPC(task, address); } Index: frysk-core/frysk/proc/live/AddressSpaceByteBuffer.java =================================================================== RCS file: /cvs/frysk/frysk-core/frysk/proc/live/AddressSpaceByteBuffer.java,v retrieving revision 1.3 diff -u -r1.3 AddressSpaceByteBuffer.java --- frysk-core/frysk/proc/live/AddressSpaceByteBuffer.java 30 Jul 2007 12:42:08 -0000 1.3 +++ frysk-core/frysk/proc/live/AddressSpaceByteBuffer.java 2 Aug 2007 10:48:33 -0000 @@ -40,7 +40,9 @@ package frysk.proc.live; import inua.eio.ByteBuffer; +import frysk.sys.Errno; import frysk.sys.Ptrace.AddressSpace; +import frysk.sys.proc.Mem; import frysk.event.Request; import frysk.proc.Manager; @@ -50,6 +52,9 @@ protected final AddressSpace addressSpace; protected final int pid; + // Direct files access if possible, or null otherwise. + final Mem mem; + protected AddressSpaceByteBuffer (int pid, AddressSpace addressSpace, long lowerExtreem, long upperExtreem) { @@ -59,6 +64,13 @@ peekRequest = new PeekRequest(); pokeRequest = new PokeRequest(); peeksRequest = new PeeksRequest(); + pokesRequest = new PokesRequest(); + + if (addressSpace == AddressSpace.TEXT + || addressSpace == AddressSpace.DATA) + mem = new Mem(pid); + else + mem = null; } public AddressSpaceByteBuffer (int pid, AddressSpace addressSpace) { @@ -137,15 +149,34 @@ { super(Manager.eventLoop); } + + private int peek(long index, byte[] bytes, int offset, int length) + { + if (mem != null) + { + try + { + return mem.pread(index, bytes, offset, length); + } + catch (Errno e) + { + // try again through address space. + } + } + + return addressSpace.peek(pid, index, length, bytes, offset); + } + public void execute () { - length = addressSpace.peek(pid, index, length, bytes, offset); + length = peek(index, bytes, offset, length); } + public int request (long index, byte[] bytes, int offset, int length) { if (isEventLoopThread()) - return addressSpace.peek(pid, index, length, bytes, offset); + return peek(index, bytes, offset, length); else synchronized (this) { this.index = index; this.bytes = bytes; @@ -162,6 +193,67 @@ return peeksRequest.request(index, bytes, offset, length); } + + private class PokesRequest + extends Request + { + private long index; + private int length; + private int offset; + private byte[] bytes; + + PokesRequest() + { + super(Manager.eventLoop); + } + + private int poke(long index, byte[] bytes, int offset, int length) + { + if (mem != null) + { + try + { + return mem.pwrite(index, bytes, offset, length); + } + catch (Errno e) + { + // try again through address space. + } + } + + // We lose here since AddressSpace isn't optimized for bulk poke. + for (int i = offset; i < length; i++) + addressSpace.poke(pid, index + i, bytes[i]); + return length; + } + + public void execute () + { + length = poke(index, bytes, offset, length); + } + + public int request (long index, byte[] bytes, + int offset, int length) + { + if (isEventLoopThread()) + return poke(index, bytes, offset, length); + else synchronized (this) { + this.index = index; + this.bytes = bytes; + this.offset = offset; + this.length = length; + request(); + return length; + } + } + } + + private final PokesRequest pokesRequest; + protected int poke(long index, byte[] bytes, int off, int len) + { + return pokesRequest.request(index, bytes, off, len); + } + protected ByteBuffer subBuffer (ByteBuffer parent, long lowerExtreem, long upperExtreem) { Index: frysk-core/frysk/proc/live/LinuxTask.java =================================================================== RCS file: /cvs/frysk/frysk-core/frysk/proc/live/LinuxTask.java,v retrieving revision 1.5 diff -u -r1.5 LinuxTask.java --- frysk-core/frysk/proc/live/LinuxTask.java 30 Jul 2007 12:42:08 -0000 1.5 +++ frysk-core/frysk/proc/live/LinuxTask.java 2 Aug 2007 10:48:33 -0000 @@ -91,13 +91,14 @@ /** - * Return the raw memory byte-buffer. + * Return the raw memory byte-buffer. This is the TEXT/DATA area. */ public ByteBuffer getRawMemory () { logger.log(Level.FINE, "Begin fillMemory\n", this); ByteOrder byteOrder = getIsa().getByteOrder(); - ByteBuffer memory = new MemorySpaceByteBuffer(getTid()); + ByteBuffer memory = new AddressSpaceByteBuffer(getTid(), + AddressSpace.DATA); memory.order(byteOrder); logger.log(Level.FINE, "End fillMemory\n", this); return memory; Index: frysk-core/frysk/proc/live/LogicalMemoryBuffer.java =================================================================== RCS file: /cvs/frysk/frysk-core/frysk/proc/live/LogicalMemoryBuffer.java,v retrieving revision 1.2 diff -u -r1.2 LogicalMemoryBuffer.java --- frysk-core/frysk/proc/live/LogicalMemoryBuffer.java 30 Jul 2007 12:42:08 -0000 1.2 +++ frysk-core/frysk/proc/live/LogicalMemoryBuffer.java 2 Aug 2007 10:48:33 -0000 @@ -127,7 +127,17 @@ return super.peek(index + r, bytes, offset + r, length - r) + r; } } + + protected void poke (long index, int value) + { + throw new UnsupportedOperationException("read only memory buffer"); + } + protected int poke(long index, byte[] bytes, int offset, int length) + { + throw new UnsupportedOperationException("read only memory buffer"); + } + protected ByteBuffer subBuffer(ByteBuffer parent, long lower, long upper) { Index: frysk-core/frysk/proc/live/MemorySpaceByteBuffer.java =================================================================== RCS file: frysk-core/frysk/proc/live/MemorySpaceByteBuffer.java diff -N frysk-core/frysk/proc/live/MemorySpaceByteBuffer.java --- frysk-core/frysk/proc/live/MemorySpaceByteBuffer.java 30 Jul 2007 12:42:08 -0000 1.5 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,193 +0,0 @@ -// This file is part of the program FRYSK. -// -// Copyright 2007 Oracle Corporation. -// Copyright 2007, Red Hat Inc. -// -// FRYSK is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License as published by -// the Free Software Foundation; version 2 of the License. -// -// FRYSK is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with FRYSK; if not, write to the Free Software Foundation, -// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -// -// In addition, as a special exception, Red Hat, Inc. gives You the -// additional right to link the code of FRYSK with code not covered -// under the GNU General Public License ("Non-GPL Code") and to -// distribute linked combinations including the two, subject to the -// limitations in this paragraph. Non-GPL Code permitted under this -// exception must only link to the code of FRYSK through those well -// defined interfaces identified in the file named EXCEPTION found in -// the source code files (the "Approved Interfaces"). The files of -// Non-GPL Code may instantiate templates or use macros or inline -// functions from the Approved Interfaces without causing the -// resulting work to be covered by the GNU General Public -// License. Only Red Hat, Inc. may make changes or additions to the -// list of Approved Interfaces. You must obey the GNU General Public -// License in all respects for all of the FRYSK code and other code -// used in conjunction with FRYSK except the Non-GPL Code covered by -// this exception. If you modify this file, you may extend this -// exception to your version of the file, but you are not obligated to -// do so. If you do not wish to provide this exception without -// modification, you must delete this exception statement from your -// version and license this file solely under the GPL without -// exception. - -package frysk.proc.live; - -import inua.eio.ByteBuffer; -import frysk.sys.Ptrace.AddressSpace; -import frysk.sys.Errno; -import frysk.sys.proc.Mem; -import frysk.event.Request; -import frysk.proc.Manager; - -public class MemorySpaceByteBuffer - extends ByteBuffer -{ - private MemorySpaceByteBuffer (long lowerExtreem, - long upperExtreem, - PeekRequest peekRequest, - PokeRequest pokeRequest, - PeeksRequest peeksRequest) - { - super (lowerExtreem, upperExtreem); - this.peekRequest = peekRequest; - this.pokeRequest = pokeRequest; - this.peeksRequest = peeksRequest; - } - public MemorySpaceByteBuffer (int pid) - { - this (0, AddressSpace.TEXT.length (), new PeekRequest(pid), - new PokeRequest(pid), new PeeksRequest(pid)); - } - - private static class PeekRequest - extends Request - { - private long index; - private int value; - private final int pid; - PeekRequest(int pid) - { - super(Manager.eventLoop); - this.pid = pid; - } - public void execute () - { - value = AddressSpace.TEXT.peek(pid, index); - } - public int request (long index) - { - if (isEventLoopThread()) - return AddressSpace.TEXT.peek(pid, index); - else synchronized (this) { - this.index = index; - request(); - return value; - } - } - } - private final PeekRequest peekRequest; - protected int peek (long index) - { - return peekRequest.request (index); - } - - private static class PokeRequest - extends Request - { - private long index; - private int value; - private final int pid; - PokeRequest(int pid) - { - super(Manager.eventLoop); - this.pid = pid; - } - public void execute () - { - AddressSpace.TEXT.poke(pid, index, value); - } - public void request (long index, int value) - { - if (isEventLoopThread()) - AddressSpace.TEXT.poke(pid, index, value); - else synchronized (this) { - this.index = index; - this.value = value; - request(); - } - } - } - private final PokeRequest pokeRequest; - protected void poke (long index, int value) - { - pokeRequest.request (index, value); - } - - private static class PeeksRequest - extends Request - { - private long index; - private int length; - private int offset; - private byte[] bytes; - private Mem mem; - private final int pid; - PeeksRequest(int pid) { - super(Manager.eventLoop); - mem = new Mem(pid); - this.pid = pid; - } - private int peek(long index, byte[] bytes, int offset, int length) { - if (mem != null) { - try { - return mem.pread (index, bytes, offset, length); - } catch (Errno ioe) { - mem = null; - } - } - return AddressSpace.TEXT.peek(pid, index, length, bytes, offset); - } - public void execute () - { - length = peek(index, bytes, offset, length); - } - public int request (long index, byte[] bytes, - int offset, int length) - { - if (isEventLoopThread()) { - return peek(index, bytes, offset, length); - } - else synchronized (this) { - this.index = index; - this.bytes = bytes; - this.offset = offset; - this.length = length; - request(); - return length; - } - } - } - private final PeeksRequest peeksRequest; - protected int peek (long index, byte[] bytes, int offset, int length) - { - return peeksRequest.request(index, bytes, offset, length); - } - - protected ByteBuffer subBuffer (ByteBuffer parent, long lowerExtreem, - long upperExtreem) - { - MemorySpaceByteBuffer up = (MemorySpaceByteBuffer)parent; - return new MemorySpaceByteBuffer (lowerExtreem, upperExtreem, - up.peekRequest, - up.pokeRequest, - up.peeksRequest); - } -} Index: frysk-core/frysk/proc/live/RegisterSetByteBuffer.java =================================================================== RCS file: /cvs/frysk/frysk-core/frysk/proc/live/RegisterSetByteBuffer.java,v retrieving revision 1.1 diff -u -r1.1 RegisterSetByteBuffer.java --- frysk-core/frysk/proc/live/RegisterSetByteBuffer.java 26 Jun 2007 22:12:52 -0000 1.1 +++ frysk-core/frysk/proc/live/RegisterSetByteBuffer.java 2 Aug 2007 10:48:33 -0000 @@ -137,14 +137,20 @@ setRegs(); } - protected long peek (long index, byte[] bytes, long off, long len) + protected int peek (long index, byte[] bytes, int off, int len) { getRegs(); - for (int i = 0; i < len; i++) { - bytes[(int)off + i] = this.bytes[(int)index + i]; - } + System.arraycopy(this.bytes, (int) index, bytes, off, len); return len; } + + protected int poke (long index, byte[] bytes, int off, int len) + { + getRegs(); + System.arraycopy(bytes, off, this.bytes, (int) index, len); + setRegs(); + return len; + } protected ByteBuffer subBuffer (ByteBuffer parent, long lowerExtreem, long upperExtreem) Index: frysk-core/frysk/proc/live/TestByteBuffer.java =================================================================== RCS file: /cvs/frysk/frysk-core/frysk/proc/live/TestByteBuffer.java,v retrieving revision 1.2 diff -u -r1.2 TestByteBuffer.java --- frysk-core/frysk/proc/live/TestByteBuffer.java 18 Jul 2007 20:00:31 -0000 1.2 +++ frysk-core/frysk/proc/live/TestByteBuffer.java 2 Aug 2007 10:48:33 -0000 @@ -41,64 +41,125 @@ import inua.eio.ByteBuffer; import frysk.junit.TestCase; -import frysk.testbed.TearDownProcess; import frysk.testbed.AttachedSelf; import frysk.testbed.LocalMemory; import frysk.sys.Ptrace.RegisterSet; import frysk.sys.Ptrace.AddressSpace; import frysk.proc.Manager; +import frysk.proc.BreakpointAddresses; + +import java.util.Arrays; public class TestByteBuffer extends TestCase { - public void tearDown() + // There are 2 sets of byte buffers to check, those that hold memory + // and those that hold various register values. + private ByteBuffer[] addressBuffers; + private ByteBuffer[] registerBuffers; + + public void setUp () throws Exception { - TearDownProcess.tearDown(); + int pid; + ByteBuffer addressSpaceByteBufferText; + ByteBuffer addressSpaceByteBufferData; + ByteBuffer memorySpaceByteBuffer; + ByteBuffer usrByteBuffer; + ByteBuffer registerByteBuffer; + ByteBuffer fpregisterByteBuffer; + ByteBuffer fpxregisterByteBuffer; + + // Watch for spawned processes, etc. + super.setUp(); + + pid = new AttachedSelf().hashCode(); + + // Text and Data are the same, but can be accessed independently. + addressSpaceByteBufferText + = new AddressSpaceByteBuffer (pid, AddressSpace.TEXT); + addressSpaceByteBufferData + = new AddressSpaceByteBuffer (pid, AddressSpace.DATA); + + // Cheat with the proc, it is not actually used if no + // breakpoints are set (testing with breakpoints set is done through + // TestTaskObserverCode in the various BreakpointMemoryView tests). + // LogicalMemory isn't writable atm, so we exclude it from those + // tests (the raw variant is of course). + frysk.proc.Proc proc = new frysk.proc.dummy.Proc(); + BreakpointAddresses breakpoints = new BreakpointAddresses(proc); + memorySpaceByteBuffer = new LogicalMemoryBuffer(pid, + AddressSpace.TEXT, + breakpoints); + + addressBuffers = new ByteBuffer[] { addressSpaceByteBufferText, + addressSpaceByteBufferData, + memorySpaceByteBuffer }; + + // The USER area is seen as a register buffer. + usrByteBuffer = new AddressSpaceByteBuffer(pid, AddressSpace.USR); + + // See how many other register sets there are. + if (RegisterSet.REGS != null) + { + registerByteBuffer + = new RegisterSetByteBuffer (pid, RegisterSet.REGS); + if (RegisterSet.FPREGS != null) + { + fpregisterByteBuffer + = new RegisterSetByteBuffer (pid, RegisterSet.FPREGS); + if (RegisterSet.FPXREGS != null) + { + fpxregisterByteBuffer + = new RegisterSetByteBuffer (pid, RegisterSet.FPXREGS); + registerBuffers = new ByteBuffer[] { usrByteBuffer, + registerByteBuffer, + fpregisterByteBuffer, + fpxregisterByteBuffer }; + } + else + registerBuffers = new ByteBuffer[] { usrByteBuffer, + registerByteBuffer, + fpregisterByteBuffer }; + } + else + registerBuffers = new ByteBuffer[] { usrByteBuffer, + registerByteBuffer }; + } + else + registerBuffers = new ByteBuffer[] { usrByteBuffer }; } - private int pid; - private ByteBuffer addressSpaceByteBuffer; - private ByteBuffer memorySpaceByteBuffer; - private ByteBuffer registerByteBuffer; - public void setUp () + public void tearDown() throws Exception { - pid = new AttachedSelf().hashCode(); - addressSpaceByteBuffer - = new AddressSpaceByteBuffer (pid, AddressSpace.TEXT); - memorySpaceByteBuffer = new MemorySpaceByteBuffer (pid); - if (RegisterSet.REGS != null) { - registerByteBuffer - = new RegisterSetByteBuffer (pid, RegisterSet.REGS); - } + addressBuffers = null; + registerBuffers = null; + + // Clean up any left stuff processes/open files/etc. + super.tearDown(); } - public void verifySlice(ByteBuffer buffer, long addr, long length) + public void verifySlice(ByteBuffer buffer, long addr, int length) { ByteBuffer slice = buffer.slice (addr, length); - byte bytes[] = new byte[ (int)length]; - buffer.get (addr, bytes, 0, (int)length); + byte bytes[] = new byte[length]; + buffer.get (addr, bytes, 0, length); for (int i = 0; i < length; i++) { assertEquals ("byte at " + i, bytes[i], slice.get (i)); } } - public void testSliceAddressSpace() - { - verifySlice(addressSpaceByteBuffer, LocalMemory.getFuncAddr(), - LocalMemory.getFuncBytes().length); - } - public void testSliceMemorySpace() + + public void testSliceAddressBuffers() { - verifySlice(memorySpaceByteBuffer, LocalMemory.getFuncAddr(), + for (int i = 0; i < addressBuffers.length; i++) + verifySlice(addressBuffers[i], LocalMemory.getFuncAddr(), LocalMemory.getFuncBytes().length); } - public void testSliceRegisterSet() + + public void testSliceRegisterBuffers() { - if (registerByteBuffer == null) { - System.out.print("<>"); - return; - } - verifySlice(registerByteBuffer, 4, 4); + for (int i = 0; i < registerBuffers.length; i++) + verifySlice(registerBuffers[i], 4, 4); } private void verifyModify(ByteBuffer buffer, long addr) @@ -108,21 +169,18 @@ buffer.putByte(addr, (byte)~oldByte); assertEquals ("modified", (byte)~oldByte, buffer.get(addr)); } - public void testModifyRegisterSet() - { - if (RegisterSet.REGS == null) { - System.out.print("<>"); - return; - } - verifyModify(registerByteBuffer, 0); - } - public void testModifyAddressSpace() + + public void testModifyRegisterBuffers() { - verifyModify(addressSpaceByteBuffer, LocalMemory.getFuncAddr()); + for (int i = 0; i < registerBuffers.length; i++) + verifyModify(registerBuffers[i], 0); } - public void testModifyMemorySpace() + + public void testModifyAddressBuffers() { - verifyModify(memorySpaceByteBuffer, LocalMemory.getFuncAddr()); + for (int i = 0; i < addressBuffers.length; i++) + if (! (addressBuffers[i] instanceof LogicalMemoryBuffer)) + verifyModify(addressBuffers[i], LocalMemory.getFuncAddr()); } private void verifyAsyncModify(ByteBuffer buffer, long addr) { @@ -171,19 +229,137 @@ asyncModify.newByte); } } - public void testAsyncRegisterSet() { - if (registerByteBuffer == null) { - System.out.print("<>"); - return; - } - verifyAsyncModify(registerByteBuffer, 0); - } - public void testAsyncAddressSpace() { - verifyAsyncModify(addressSpaceByteBuffer, - LocalMemory.getFuncAddr()); - } - public void testAsyncMemorySpace() { - verifyAsyncModify(memorySpaceByteBuffer, - LocalMemory.getFuncAddr()); + public void testAsyncRegisterBuffers() { + for (int i = 0; i < registerBuffers.length; i++) + verifyAsyncModify(registerBuffers[0], 0); + } + + public void testAsyncAddressBuffers() { + for (int i = 0; i < addressBuffers.length; i++) + if (! (addressBuffers[i] instanceof LogicalMemoryBuffer)) + verifyAsyncModify(addressBuffers[i], + LocalMemory.getFuncAddr()); + } + + public void verifyPeeks(ByteBuffer buffer, long addr, byte[] origBytes) + { + byte bytes[] = new byte[origBytes.length]; + buffer.get(addr, bytes, 0, bytes.length); + for (int i = 0; i < bytes.length; i++) + assertEquals ("byte at " + i, bytes[i], origBytes[i]); + } + + public void testAddressBufferPeeks() + { + long addr = LocalMemory.getFuncAddr(); + byte[] origBytes = LocalMemory.getFuncBytes(); + for (int i = 0; i < addressBuffers.length; i++) + verifyPeeks(addressBuffers[i], addr, origBytes); + } + + public void testRegisterBufferPeeks() + { + // Check that simple get loop is similar to bulk get. + long addr = 4; + byte[] origBytes = new byte[16]; + for (int i = 0; i < registerBuffers.length; i++) + { + for (int j = 0; j < origBytes.length; j++) + origBytes[j] = registerBuffers[i].get(addr + j); + verifyPeeks(registerBuffers[i], addr, origBytes); + } + } + private class AsyncPeeks + implements Runnable + { + private ByteBuffer buffer; + private long addr; + private int length; + private byte[] bytes; + private Exception e; + AsyncPeeks (ByteBuffer buffer, long addr, int length) + { + this.buffer = buffer; + this.addr = addr; + this.length = length; + this.bytes = new byte[length]; + } + public void run () + { + try { + buffer.get (addr, bytes, 0, length); + } + catch (Exception e) { + this.e = e; + } + Manager.eventLoop.requestStop(); + } + void call (byte[] origBytes) + { + // Force the event loop to running on this thread. Ugly, and is to + // to be removed when bug #4688 is resolved. + Manager.eventLoop.runPolling(1); + new Thread (this).start(); + assertTrue("waiting for async peeks", + Manager.eventLoop.runPolling(getTimeoutMilliseconds())); + if (e != null) + throw new RuntimeException (e); + for (int i = 0; i < length; i++) { + assertEquals ("byte at " + i, bytes[i], origBytes[i]); + } + } + } + + public void testAsyncPeeks () + { + byte[] origBytes = LocalMemory.getFuncBytes(); + for (int i = 0; i < addressBuffers.length; i++) + new AsyncPeeks(addressBuffers[i], LocalMemory.getFuncAddr(), + LocalMemory.getFuncBytes().length).call(origBytes); + } + + public void testAsycnPeeksRegisters() + { + // Check position() and (async) get() + int length = 8; + byte[] origBytes = new byte[length]; + long address = 4; + for (int i = 0; i < registerBuffers.length; i++) + { + registerBuffers[i].position(address); + registerBuffers[i].get(origBytes); + new AsyncPeeks(registerBuffers[i], address, + length).call(origBytes); + } } + + private void verifyBulkPut(ByteBuffer buffer, long addr, int len) + { + // Pasting the same bytes back over the old buffer in bulk + // and read it back in. + byte[] oldBytes = new byte[len]; + buffer.position(addr); + buffer.get(oldBytes); + buffer.position(addr); + buffer.put(oldBytes); + byte[] newBytes = new byte[len]; + buffer.position(addr); + buffer.get(newBytes); + assertTrue(Arrays.equals(oldBytes, newBytes)); + } + + public void testBulkPutRegisterBuffers() + { + for (int i = 0; i < registerBuffers.length; i++) + verifyBulkPut(registerBuffers[i], 4, 4); + } + + public void testBulkPutAddressBuffers() + { + for (int i = 0; i < addressBuffers.length; i++) + if (! (addressBuffers[i] instanceof LogicalMemoryBuffer)) + verifyBulkPut(addressBuffers[i], LocalMemory.getFuncAddr(), + LocalMemory.getFuncBytes().length); + } + } Index: frysk-core/frysk/proc/live/TestMemorySpaceByteBuffer.java =================================================================== RCS file: frysk-core/frysk/proc/live/TestMemorySpaceByteBuffer.java diff -N frysk-core/frysk/proc/live/TestMemorySpaceByteBuffer.java --- frysk-core/frysk/proc/live/TestMemorySpaceByteBuffer.java 30 Jul 2007 12:42:08 -0000 1.3 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,123 +0,0 @@ -// This file is part of the program FRYSK. -// -// Copyright 2007 Oracle Corporation. -// Copyright 2007, Red Hat Inc. -// -// FRYSK is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License as published by -// the Free Software Foundation; version 2 of the License. -// -// FRYSK is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with FRYSK; if not, write to the Free Software Foundation, -// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. -// -// In addition, as a special exception, Red Hat, Inc. gives You the -// additional right to link the code of FRYSK with code not covered -// under the GNU General Public License ("Non-GPL Code") and to -// distribute linked combinations including the two, subject to the -// limitations in this paragraph. Non-GPL Code permitted under this -// exception must only link to the code of FRYSK through those well -// defined interfaces identified in the file named EXCEPTION found in -// the source code files (the "Approved Interfaces"). The files of -// Non-GPL Code may instantiate templates or use macros or inline -// functions from the Approved Interfaces without causing the -// resulting work to be covered by the GNU General Public -// License. Only Red Hat, Inc. may make changes or additions to the -// list of Approved Interfaces. You must obey the GNU General Public -// License in all respects for all of the FRYSK code and other code -// used in conjunction with FRYSK except the Non-GPL Code covered by -// this exception. If you modify this file, you may extend this -// exception to your version of the file, but you are not obligated to -// do so. If you do not wish to provide this exception without -// modification, you must delete this exception statement from your -// version and license this file solely under the GPL without -// exception. - -package frysk.proc.live; - -import frysk.junit.TestCase; -import frysk.testbed.TearDownProcess; -import frysk.testbed.AttachedSelf; -import frysk.testbed.LocalMemory; -import frysk.proc.Manager; - -public class TestMemorySpaceByteBuffer - extends TestCase -{ - public void tearDown() - { - TearDownProcess.tearDown(); - } - private int pid; - private MemorySpaceByteBuffer memorySpaceByteBuffer; - - public void setUp () - { - pid = new AttachedSelf().hashCode(); - memorySpaceByteBuffer = new MemorySpaceByteBuffer (pid); - } - - public void testPeeks () - { - long addr = LocalMemory.getFuncAddr(); - int length = LocalMemory.getFuncBytes().length; - byte bytes[] = new byte[(int)length]; - memorySpaceByteBuffer.peek (addr, bytes, 0, length); - byte[] origBytes = LocalMemory.getFuncBytes(); - for (int i = 0; i < length; i++) { - assertEquals ("byte at " + i, bytes[i], origBytes[i]); - } - } - - private class AsyncPeeks - implements Runnable - { - private MemorySpaceByteBuffer buffer; - private long addr; - private int length; - private byte[] bytes; - private Exception e; - AsyncPeeks (MemorySpaceByteBuffer buffer, long addr, int length) - { - this.buffer = buffer; - this.addr = addr; - this.length = length; - this.bytes = new byte[length]; - } - public void run () - { - try { - buffer.peek (addr, bytes, 0, length); - } - catch (Exception e) { - this.e = e; - } - Manager.eventLoop.requestStop(); - } - void call () - { - // Force the event loop to running on this thread. Ugly, and is to - // to be removed when bug #4688 is resolved. - Manager.eventLoop.runPolling(1); - new Thread (this).start(); - assertTrue("waiting for async peeks", - Manager.eventLoop.runPolling(getTimeoutMilliseconds())); - if (e != null) - throw new RuntimeException (e); - byte[] origBytes = LocalMemory.getFuncBytes(); - for (int i = 0; i < length; i++) { - assertEquals ("byte at " + i, bytes[i], origBytes[i]); - } - } - } - public void testAsyncPeeks () - { - new AsyncPeeks(memorySpaceByteBuffer, LocalMemory.getFuncAddr(), - LocalMemory.getFuncBytes().length).call(); - } -} Index: frysk-sys/inua/eio/ByteBuffer.java =================================================================== RCS file: /cvs/frysk/frysk-sys/inua/eio/ByteBuffer.java,v retrieving revision 1.2 diff -u -r1.2 ByteBuffer.java --- frysk-sys/inua/eio/ByteBuffer.java 30 Jul 2007 12:42:09 -0000 1.2 +++ frysk-sys/inua/eio/ByteBuffer.java 2 Aug 2007 10:48:35 -0000 @@ -372,6 +372,21 @@ return get(dst, 0, dst.length); } + public ByteBuffer put (byte[] src, int off, int len) + throws BufferUnderflowException + { + if (ULong.GT(len, remaining())) + throw new BufferUnderflowException(); + poke(cursor, src, off, len); + cursor += len; + return this; + } + + public final ByteBuffer put (byte[] src) throws BufferUnderflowException + { + return put(src, 0, src.length); + } + protected ByteOrdered byteOrdered; public final ByteOrder order ()