1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-12 11:35:21 +02:00

[248636] Changes to the memory cache to allow to keep it private.

This commit is contained in:
Marc Khouzam 2008-10-10 20:07:27 +00:00
parent a9b0d0a49a
commit c2468b0c14
2 changed files with 139 additions and 163 deletions

View file

@ -1,3 +1,13 @@
/*******************************************************************************
* Copyright (c) 2008 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Ericsson - initial API and implementation
*******************************************************************************/
package org.eclipse.dd.gdb.internal.provisional.service; package org.eclipse.dd.gdb.internal.provisional.service;
import java.util.Hashtable; import java.util.Hashtable;
@ -34,8 +44,6 @@ public class GDBMemory_7_0 extends MIMemory {
register(new String[] { MIMemory.class.getName(), IMemory.class.getName(), GDBMemory_7_0.class.getName()}, register(new String[] { MIMemory.class.getName(), IMemory.class.getName(), GDBMemory_7_0.class.getName()},
new Hashtable<String, String>()); new Hashtable<String, String>());
setMemoryCache(new GDBMemoryCache());
requestMonitor.done(); requestMonitor.done();
} }
@ -45,59 +53,47 @@ public class GDBMemory_7_0 extends MIMemory {
super.shutdown(requestMonitor); super.shutdown(requestMonitor);
} }
protected class GDBMemoryCache extends MIMemoryCache { @Override
@Override protected void readMemoryBlock(IDMContext dmc, IAddress address, long offset,
protected void readMemoryBlock(IDMContext dmc, IAddress address, final long offset, int word_size, int count, DataRequestMonitor<MemoryByte[]> drm)
final int word_size, final int count, final DataRequestMonitor<MemoryByte[]> drm) {
{ IDMContext threadOrMemoryDmc = dmc;
IDMContext threadOrMemoryDmc = dmc;
IMIContainerDMContext containerCtx = DMContexts.getAncestorOfType(dmc, IMIContainerDMContext.class); IMIContainerDMContext containerCtx = DMContexts.getAncestorOfType(dmc, IMIContainerDMContext.class);
if(containerCtx != null) { if(containerCtx != null) {
IGDBProcesses procService = getServicesTracker().getService(IGDBProcesses.class); IGDBProcesses procService = getServicesTracker().getService(IGDBProcesses.class);
if (procService != null) { if (procService != null) {
IMIExecutionDMContext[] execCtxs = procService.getExecutionContexts(containerCtx); IMIExecutionDMContext[] execCtxs = procService.getExecutionContexts(containerCtx);
// Return any thread... let's take the first one. // Return any thread... let's take the first one.
if (execCtxs != null && execCtxs.length > 0) { if (execCtxs != null && execCtxs.length > 0) {
threadOrMemoryDmc = execCtxs[0]; threadOrMemoryDmc = execCtxs[0];
}
} }
} }
super.readMemoryBlock(threadOrMemoryDmc, address, offset, word_size, count, drm);
} }
/** super.readMemoryBlock(threadOrMemoryDmc, address, offset, word_size, count, drm);
* @param memoryDMC
* @param address
* @param offset
* @param word_size
* @param count
* @param buffer
* @param rm
*/
@Override
protected void writeMemoryBlock(final IDMContext dmc, final IAddress address, final long offset,
final int word_size, final int count, final byte[] buffer, final RequestMonitor rm)
{
IDMContext threadOrMemoryDmc = dmc;
IMIContainerDMContext containerCtx = DMContexts.getAncestorOfType(dmc, IMIContainerDMContext.class);
if(containerCtx != null) {
IGDBProcesses procService = getServicesTracker().getService(IGDBProcesses.class);
if (procService != null) {
IMIExecutionDMContext[] execCtxs = procService.getExecutionContexts(containerCtx);
// Return any thread... let's take the first one.
if (execCtxs != null && execCtxs.length > 0) {
threadOrMemoryDmc = execCtxs[0];
}
}
}
super.writeMemoryBlock(threadOrMemoryDmc, address, offset, word_size, count, buffer, rm);
}
} }
@Override
protected void writeMemoryBlock(IDMContext dmc, IAddress address, long offset,
int word_size, int count, byte[] buffer, RequestMonitor rm)
{
IDMContext threadOrMemoryDmc = dmc;
IMIContainerDMContext containerCtx = DMContexts.getAncestorOfType(dmc, IMIContainerDMContext.class);
if(containerCtx != null) {
IGDBProcesses procService = getServicesTracker().getService(IGDBProcesses.class);
if (procService != null) {
IMIExecutionDMContext[] execCtxs = procService.getExecutionContexts(containerCtx);
// Return any thread... let's take the first one.
if (execCtxs != null && execCtxs.length > 0) {
threadOrMemoryDmc = execCtxs[0];
}
}
}
super.writeMemoryBlock(threadOrMemoryDmc, address, offset, word_size, count, buffer, rm);
}
} }

View file

@ -73,6 +73,9 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
} }
} }
// Back-end commands cache
private CommandCache fCommandCache;
// Local memory cache
private MIMemoryCache fMemoryCache; private MIMemoryCache fMemoryCache;
/** /**
@ -111,12 +114,16 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
* @param requestMonitor * @param requestMonitor
*/ */
private void doInitialize(final RequestMonitor requestMonitor) { private void doInitialize(final RequestMonitor requestMonitor) {
// Create the command cache
ICommandControlService commandControl = getServicesTracker().getService(ICommandControlService.class);
fCommandCache = new CommandCache(getSession(), commandControl);
fCommandCache.setContextAvailable(commandControl.getContext(), true);
// Register this service // Register this service
register(new String[] { MIMemory.class.getName(), IMemory.class.getName() }, new Hashtable<String, String>()); register(new String[] { MIMemory.class.getName(), IMemory.class.getName() }, new Hashtable<String, String>());
// Create the memory requests cache // Create the memory requests cache
setMemoryCache(new MIMemoryCache()); fMemoryCache = new MIMemoryCache();
// Register as service event listener // Register as service event listener
getSession().addServiceEventListener(this, null); getSession().addServiceEventListener(this, null);
@ -149,15 +156,6 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
return MIPlugin.getBundleContext(); return MIPlugin.getBundleContext();
} }
/**
* This method resets the memory cache. It allows an overriding class to provide
* its own overridden memory cache class.
*
* @since 1.1
*/
protected void setMemoryCache(MIMemoryCache cache) { fMemoryCache = cache; }
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// IMemory // IMemory
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@ -279,6 +277,86 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
fMemoryCache.setMemory(memoryDMC, address, offset, word_size, count * length, buffer, rm); fMemoryCache.setMemory(memoryDMC, address, offset, word_size, count * length, buffer, rm);
} }
///////////////////////////////////////////////////////////////////////
// Back-end functions
///////////////////////////////////////////////////////////////////////
/**
* @param memoryDMC
* @param address
* @param offset
* @param word_size
* @param count
* @param drm
*
* @since 1.1
*/
protected void readMemoryBlock(IDMContext dmc, IAddress address, final long offset,
final int word_size, final int count, final DataRequestMonitor<MemoryByte[]> drm)
{
/* To simplify the parsing of the MI result, we request the output to
* be on 1 row of [count] columns, no char interpretation.
*/
int mode = MIFormat.HEXADECIMAL;
int nb_rows = 1;
int nb_cols = count;
Character asChar = null;
fCommandCache.execute(
new MIDataReadMemory(dmc, offset, address.toString(), mode, word_size, nb_rows, nb_cols, asChar),
new DataRequestMonitor<MIDataReadMemoryInfo>(getExecutor(), drm) {
@Override
protected void handleSuccess() {
// Retrieve the memory block
drm.setData(getData().getMIMemoryBlock());
drm.done();
}
@Override
protected void handleFailure() {
// Bug234289: If memory read fails, return a block marked as invalid
MemoryByte[] block = new MemoryByte[word_size * count];
for (int i = 0; i < block.length; i++)
block[i] = new MemoryByte((byte) 0, (byte) 0);
drm.setData(block);
drm.done();
}
}
);
}
/**
* @param memoryDMC
* @param address
* @param offset
* @param word_size
* @param count
* @param buffer
* @param rm
*
* @since 1.1
*/
protected void writeMemoryBlock(final IDMContext dmc, final IAddress address, final long offset,
final int word_size, final int count, final byte[] buffer, final RequestMonitor rm)
{
// Each byte is written individually (GDB power...)
// so we need to keep track of the count
final CountingRequestMonitor countingRM = new CountingRequestMonitor(getExecutor(), rm);
countingRM.setDoneCount(count);
// We will format the individual bytes in decimal
int format = MIFormat.DECIMAL;
String baseAddress = address.toString();
// Issue an MI request for each byte to write
for (int i = 0; i < count; i++) {
String value = new Byte(buffer[i]).toString();
fCommandCache.execute(
new MIDataWriteMemory(dmc, offset + i, baseAddress, format, word_size, value),
new DataRequestMonitor<MIDataWriteMemoryInfo>(getExecutor(), countingRM)
);
}
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// Event handlers // Event handlers
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -290,10 +368,11 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
@DsfServiceEventHandler @DsfServiceEventHandler
public void eventDispatched(IResumedDMEvent e) { public void eventDispatched(IResumedDMEvent e) {
if (e instanceof IContainerResumedDMEvent) { if (e instanceof IContainerResumedDMEvent) {
fMemoryCache.setTargetAvailable(e.getDMContext(), false); fCommandCache.setContextAvailable(e.getDMContext(), false);
} }
if (e.getReason() != StateChangeReason.STEP) { if (e.getReason() != StateChangeReason.STEP) {
fCommandCache.reset();
fMemoryCache.reset(); fMemoryCache.reset();
} }
} }
@ -305,8 +384,9 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
@DsfServiceEventHandler @DsfServiceEventHandler
public void eventDispatched(ISuspendedDMEvent e) { public void eventDispatched(ISuspendedDMEvent e) {
if (e instanceof IContainerSuspendedDMEvent) { if (e instanceof IContainerSuspendedDMEvent) {
fMemoryCache.setTargetAvailable(e.getDMContext(), true); fCommandCache.setContextAvailable(e.getDMContext(), true);
} }
fCommandCache.reset();
fMemoryCache.reset(); fMemoryCache.reset();
} }
@ -449,44 +529,20 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
// MIMemoryCache // MIMemoryCache
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
/** private class MIMemoryCache {
* This class can now be overridden.
*
* @since 1.1
*/
protected class MIMemoryCache {
// Back-end commands cache
private CommandCache fCommandCache;
// The memory cache data structure // The memory cache data structure
private SortedMemoryBlockList fMemoryBlockList; private SortedMemoryBlockList fMemoryBlockList;
public MIMemoryCache() { public MIMemoryCache() {
// Create the command cache
ICommandControlService commandControl = getServicesTracker().getService(ICommandControlService.class);
fCommandCache = new CommandCache(getSession(), commandControl);
fCommandCache.setContextAvailable(commandControl.getContext(), true);
// Create the memory block cache // Create the memory block cache
fMemoryBlockList = new SortedMemoryBlockList(); fMemoryBlockList = new SortedMemoryBlockList();
} }
public void reset() { public void reset() {
// Clear the command cache
fCommandCache.reset();
// Clear the memory cache // Clear the memory cache
fMemoryBlockList.clear(); fMemoryBlockList.clear();
} }
public void setTargetAvailable(IDMContext dmc, boolean isAvailable) {
fCommandCache.setContextAvailable(dmc, isAvailable);
}
public boolean isTargetAvailable(IDMContext dmc) {
return fCommandCache.isTargetAvailable(dmc);
}
/** /**
* This function walks the address-sorted memory block list to identify * This function walks the address-sorted memory block list to identify
* the 'missing' blocks (i.e. the holes) that need to be fetched on the target. * the 'missing' blocks (i.e. the holes) that need to be fetched on the target.
@ -849,83 +905,6 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
} }
}); });
} }
///////////////////////////////////////////////////////////////////////
// Back-end functions
///////////////////////////////////////////////////////////////////////
/**
* @param memoryDMC
* @param address
* @param offset
* @param word_size
* @param count
* @param drm
*/
protected void readMemoryBlock(IDMContext dmc, IAddress address, final long offset,
final int word_size, final int count, final DataRequestMonitor<MemoryByte[]> drm)
{
/* To simplify the parsing of the MI result, we request the output to
* be on 1 row of [count] columns, no char interpretation.
*/
int mode = MIFormat.HEXADECIMAL;
int nb_rows = 1;
int nb_cols = count;
Character asChar = null;
fCommandCache.execute(
new MIDataReadMemory(dmc, offset, address.toString(), mode, word_size, nb_rows, nb_cols, asChar),
new DataRequestMonitor<MIDataReadMemoryInfo>(getExecutor(), drm) {
@Override
protected void handleSuccess() {
// Retrieve the memory block
drm.setData(getData().getMIMemoryBlock());
drm.done();
}
@Override
protected void handleFailure() {
// Bug234289: If memory read fails, return a block marked as invalid
MemoryByte[] block = new MemoryByte[word_size * count];
for (int i = 0; i < block.length; i++)
block[i] = new MemoryByte((byte) 0, (byte) 0);
drm.setData(block);
drm.done();
}
}
);
}
/**
* @param memoryDMC
* @param address
* @param offset
* @param word_size
* @param count
* @param buffer
* @param rm
*/
protected void writeMemoryBlock(final IDMContext dmc, final IAddress address, final long offset,
final int word_size, final int count, final byte[] buffer, final RequestMonitor rm)
{
// Each byte is written individually (GDB power...)
// so we need to keep track of the count
final CountingRequestMonitor countingRM = new CountingRequestMonitor(getExecutor(), rm);
countingRM.setDoneCount(count);
// We will format the individual bytes in decimal
int format = MIFormat.DECIMAL;
String baseAddress = address.toString();
// Issue an MI request for each byte to write
for (int i = 0; i < count; i++) {
String value = new Byte(buffer[i]).toString();
fCommandCache.execute(
new MIDataWriteMemory(dmc, offset + i, baseAddress, format, word_size, value),
new DataRequestMonitor<MIDataWriteMemoryInfo>(getExecutor(), countingRM)
);
}
}
} }
/** /**
@ -933,6 +912,7 @@ public class MIMemory extends AbstractDsfService implements IMemory, ICachingSer
* @since 1.1 * @since 1.1
*/ */
public void flushCache(IDMContext context) { public void flushCache(IDMContext context) {
fCommandCache.reset();
fMemoryCache.reset(); fMemoryCache.reset();
} }
} }