Rename load/unload to mount/unmount, add suspend for temporary unload (e.g. containing chunk unload).
This commit is contained in:
@@ -15,7 +15,7 @@ import li.cil.sedna.api.device.MemoryMappedDevice;
|
||||
* in the guest system.
|
||||
* <p>
|
||||
* To listen to lifecycle events of the VM and the device, register to the event
|
||||
* bus provided via {@link VMContext#getEventBus()} in {@link #load(VMContext)}.
|
||||
* bus provided via {@link VMContext#getEventBus()} in {@link #mount(VMContext)}.
|
||||
*
|
||||
* @see li.cil.oc2.api.bus.device.provider.BlockDeviceProvider
|
||||
* @see li.cil.oc2.api.bus.device.provider.ItemDeviceProvider
|
||||
@@ -35,7 +35,7 @@ public interface VMDevice extends Device {
|
||||
* @param context the virtual machine context.
|
||||
* @return {@code true} if the device was loaded successfully; {@code false} otherwise.
|
||||
*/
|
||||
VMDeviceLoadResult load(VMContext context);
|
||||
VMDeviceLoadResult mount(VMContext context);
|
||||
|
||||
/**
|
||||
* Called when the device is removed from the context it was loaded with.
|
||||
@@ -43,7 +43,17 @@ public interface VMDevice extends Device {
|
||||
* This can happen because the VM was stopped or the device was removed from
|
||||
* the device bus that connected it to the VM, for example.
|
||||
* <p>
|
||||
* Intended for releasing resources acquired in {@link #load(VMContext)}.
|
||||
* Intended for releasing resources acquired in {@link #mount(VMContext)}.
|
||||
*/
|
||||
void unload();
|
||||
void unmount();
|
||||
|
||||
/**
|
||||
* Called when the device is suspended.
|
||||
* <p>
|
||||
* This can happen when the world area containing the context the device was loaded in is unloaded,
|
||||
* e.g. due to player moving too far away from the area.
|
||||
* <p>
|
||||
* Intended for soft-releasing resources acquired in {@link #mount(VMContext)}.
|
||||
*/
|
||||
void suspend();
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import net.minecraft.util.text.ITextComponent;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* {@link VMDevice}s may signal the result of their {@link VMDevice#load(VMContext)} operations.
|
||||
* {@link VMDevice}s may signal the result of their {@link VMDevice#mount(VMContext)} operations.
|
||||
*/
|
||||
public final class VMDeviceLoadResult {
|
||||
/**
|
||||
|
||||
@@ -7,7 +7,7 @@ import java.util.OptionalInt;
|
||||
|
||||
/**
|
||||
* Allows reserving interrupts on the primary interrupt controller of a virtual machine
|
||||
* during a {@link VMDevice#load(VMContext)} call.
|
||||
* during a {@link VMDevice#mount(VMContext)} call.
|
||||
* <p>
|
||||
* Allocated interrupts should be persisted and used in {@link #claimInterrupt(int)}
|
||||
* when restoring from a saved state to ensure correct behaviour of the loaded virtual
|
||||
|
||||
@@ -7,7 +7,7 @@ import java.util.OptionalLong;
|
||||
|
||||
/**
|
||||
* Allows adding {@link MemoryMappedDevice}s to the memory map of a virtual machine
|
||||
* during a {@link VMDevice#load(VMContext)} call.
|
||||
* during a {@link VMDevice#mount(VMContext)} call.
|
||||
* <p>
|
||||
* Allocated addresses should be persisted and used in {@link #claimMemoryRange(long, MemoryMappedDevice)}
|
||||
* when restoring from a saved state to ensure correct behaviour of the loaded virtual
|
||||
|
||||
@@ -40,7 +40,7 @@ public interface VMContext {
|
||||
/**
|
||||
* Allows adding {@link MemoryMappedDevice}s to the VM's {@link MemoryMap}.
|
||||
* <p>
|
||||
* {@link MemoryMappedDevice}s can only be added inside {@link VMDevice#load(VMContext)}.
|
||||
* {@link MemoryMappedDevice}s can only be added inside {@link VMDevice#mount(VMContext)}.
|
||||
* Trying to add devices after that method has returned will result in an exception.
|
||||
* <p>
|
||||
* Added devices will be automatically removed when the {@link VMDevice} that added it
|
||||
@@ -54,7 +54,7 @@ public interface VMContext {
|
||||
/**
|
||||
* Allows claiming interrupts for use with the VM's {@link InterruptController}.
|
||||
* <p>
|
||||
* Interrupts can only be claimed inside {@link VMDevice#load(VMContext)}.
|
||||
* Interrupts can only be claimed inside {@link VMDevice#mount(VMContext)}.
|
||||
* Trying to claim interrupts after that method has returned will result in an exception.
|
||||
* <p>
|
||||
* Claimed interrupts will automatically be released when the {@link VMDevice} that
|
||||
@@ -73,7 +73,7 @@ public interface VMContext {
|
||||
* running VMs.
|
||||
* <p>
|
||||
* Devices failing to reserve the memory they would use should fail their
|
||||
* {@link VMDevice#load(VMContext)}.
|
||||
* {@link VMDevice#mount(VMContext)}.
|
||||
* <p>
|
||||
* Memory will automatically be released when the {@link VMDevice} that claimed
|
||||
* it is unloaded, e.g. because it is removed from the {@link DeviceBus} or the
|
||||
@@ -97,7 +97,7 @@ public interface VMContext {
|
||||
/**
|
||||
* Waits for the executor thread of the virtual machine to finish running.
|
||||
* <p>
|
||||
* Events subscribers can only be registered inside {@link VMDevice#load(VMContext)}.
|
||||
* Events subscribers can only be registered inside {@link VMDevice#mount(VMContext)}.
|
||||
* Trying to register subscribers after that method has returned will result in an
|
||||
* exception.
|
||||
* <p>
|
||||
|
||||
@@ -6,7 +6,7 @@ import li.cil.oc2.api.bus.device.vm.context.VMContext;
|
||||
/**
|
||||
* Fired exactly once, when the VM first starts running.
|
||||
* <p>
|
||||
* Fired after all devices reported success from {@link VMDevice#load(VMContext)}.
|
||||
* Fired after all devices reported success from {@link VMDevice#mount(VMContext)}.
|
||||
* <p>
|
||||
* If a running VM is restored from a saved state, this event will not be fired. It is
|
||||
* intended for initializing the VM state on boot, e.g. by loading initial executable
|
||||
@@ -14,7 +14,7 @@ import li.cil.oc2.api.bus.device.vm.context.VMContext;
|
||||
* <p>
|
||||
* Listeners of this event may throw a {@link VMInitializationException} in case
|
||||
* initialization fails. For some devices it may be too costly to perform a full
|
||||
* validity check in {@link VMDevice#load(VMContext)}. These devices may still cause
|
||||
* validity check in {@link VMDevice#mount(VMContext)}. These devices may still cause
|
||||
* a startup to fail this way.
|
||||
* <p>
|
||||
* <em>This is invoked from the worker thread running the VM.</em>
|
||||
|
||||
@@ -6,7 +6,7 @@ import li.cil.oc2.api.bus.device.vm.context.VMContext;
|
||||
/**
|
||||
* Fired when the VM resumes running.
|
||||
* <p>
|
||||
* Fired after all devices reported success from {@link VMDevice#load(VMContext)}.
|
||||
* Fired after all devices reported success from {@link VMDevice#mount(VMContext)}.
|
||||
* <p>
|
||||
* Fired on initial boot-up as well as when the VM resumes after being restored
|
||||
* from a saved state as well as when continuing to run after being paused for
|
||||
|
||||
@@ -55,7 +55,7 @@ public abstract class AbstractBlockDeviceVMDevice<TBlock extends BlockDevice, TI
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public VMDeviceLoadResult load(final VMContext context) {
|
||||
public VMDeviceLoadResult mount(final VMContext context) {
|
||||
data = createBlockDevice();
|
||||
|
||||
if (!allocateDevice(context)) {
|
||||
@@ -84,20 +84,25 @@ public abstract class AbstractBlockDeviceVMDevice<TBlock extends BlockDevice, TI
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload() {
|
||||
public void unmount() {
|
||||
// Since we cannot serialize the data in a regular serialize call due to the
|
||||
// actual data being unloaded at that point, but want to permanently persist
|
||||
// it (it's the contents of the block device) we need to serialize it in the
|
||||
// unload, too. Don't need to wait for the job, though.
|
||||
serializeData();
|
||||
|
||||
suspend();
|
||||
deviceTag = null;
|
||||
address.clear();
|
||||
interrupt.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void suspend() {
|
||||
data = null;
|
||||
jobHandle = null;
|
||||
|
||||
device = null;
|
||||
deviceTag = null;
|
||||
address.clear();
|
||||
interrupt.clear();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
|
||||
@@ -48,7 +48,7 @@ public final class ByteBufferFlashMemoryVMDevice extends IdentityProxy<ItemStack
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public VMDeviceLoadResult load(final VMContext context) {
|
||||
public VMDeviceLoadResult mount(final VMContext context) {
|
||||
if (!allocateDevice(context)) {
|
||||
return VMDeviceLoadResult.fail();
|
||||
}
|
||||
@@ -67,12 +67,17 @@ public final class ByteBufferFlashMemoryVMDevice extends IdentityProxy<ItemStack
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload() {
|
||||
public void unmount() {
|
||||
suspend();
|
||||
deviceTag = null;
|
||||
address.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void suspend() {
|
||||
memoryMap = null;
|
||||
data = null;
|
||||
device = null;
|
||||
deviceTag = null;
|
||||
address.clear();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
|
||||
@@ -30,7 +30,7 @@ public final class FirmwareFlashMemoryVMDevice extends IdentityProxy<ItemStack>
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public VMDeviceLoadResult load(final VMContext context) {
|
||||
public VMDeviceLoadResult mount(final VMContext context) {
|
||||
memoryMap = context.getMemoryMap();
|
||||
|
||||
context.getEventBus().register(this);
|
||||
@@ -39,7 +39,12 @@ public final class FirmwareFlashMemoryVMDevice extends IdentityProxy<ItemStack>
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload() {
|
||||
public void unmount() {
|
||||
suspend();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void suspend() {
|
||||
memoryMap = null;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ public final class MemoryDevice extends IdentityProxy<ItemStack> implements VMDe
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public VMDeviceLoadResult load(final VMContext context) {
|
||||
public VMDeviceLoadResult mount(final VMContext context) {
|
||||
if (!allocateDevice(context)) {
|
||||
return VMDeviceLoadResult.fail();
|
||||
}
|
||||
@@ -62,16 +62,22 @@ public final class MemoryDevice extends IdentityProxy<ItemStack> implements VMDe
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload() {
|
||||
public void unmount() {
|
||||
suspend();
|
||||
|
||||
// Memory is volatile, so free up our persisted blob when device is unloaded.
|
||||
BlobStorage.freeHandle(blobHandle);
|
||||
blobHandle = null;
|
||||
jobHandle = null;
|
||||
|
||||
device = null;
|
||||
address.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void suspend() {
|
||||
device = null;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void handleResumingRunningEvent(final VMResumingRunningEvent event) {
|
||||
awaitStorageOperation();
|
||||
|
||||
@@ -60,7 +60,7 @@ public final class NetworkInterfaceCardItemDevice extends IdentityProxy<ItemStac
|
||||
}
|
||||
|
||||
@Override
|
||||
public VMDeviceLoadResult load(final VMContext context) {
|
||||
public VMDeviceLoadResult mount(final VMContext context) {
|
||||
device = new VirtIONetworkDevice(context.getMemoryMap());
|
||||
|
||||
if (!address.claim(context, device)) {
|
||||
@@ -83,13 +83,18 @@ public final class NetworkInterfaceCardItemDevice extends IdentityProxy<ItemStac
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload() {
|
||||
device = null;
|
||||
public void unmount() {
|
||||
suspend();
|
||||
isRunning = false;
|
||||
address.clear();
|
||||
interrupt.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void suspend() {
|
||||
device = null;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void handlePausingEvent(final VMPausingEvent event) {
|
||||
isRunning = false;
|
||||
|
||||
@@ -322,10 +322,10 @@ public final class RobotEntity extends Entity implements Robot {
|
||||
public void remove(final boolean keepData) {
|
||||
super.remove(keepData);
|
||||
|
||||
handleUnload();
|
||||
virtualMachine.suspend();
|
||||
|
||||
// Full unload to release out-of-nbt persisted runtime-only data such as ram.
|
||||
virtualMachine.state.vmAdapter.unload();
|
||||
virtualMachine.state.vmAdapter.unmount();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -449,7 +449,7 @@ public final class RobotEntity extends Entity implements Robot {
|
||||
}
|
||||
|
||||
unregisterListeners();
|
||||
handleUnload();
|
||||
virtualMachine.suspend();
|
||||
}
|
||||
|
||||
private void handleWorldUnload(final WorldEvent.Unload event) {
|
||||
@@ -458,11 +458,7 @@ public final class RobotEntity extends Entity implements Robot {
|
||||
}
|
||||
|
||||
unregisterListeners();
|
||||
handleUnload();
|
||||
}
|
||||
|
||||
private void handleUnload() {
|
||||
virtualMachine.unload();
|
||||
virtualMachine.suspend();
|
||||
}
|
||||
|
||||
private void openTerminalScreen(final ServerPlayerEntity player) {
|
||||
|
||||
@@ -242,7 +242,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
|
||||
// super.remove() calls onUnload. This in turn only suspends, but we want to do
|
||||
// a full clean-up when we get destroyed, so stuff inside us can delete out-of-nbt
|
||||
// persisted runtime-only data such as ram.
|
||||
virtualMachine.state.vmAdapter.unload();
|
||||
virtualMachine.state.vmAdapter.unmount();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -333,7 +333,7 @@ public final class ComputerTileEntity extends AbstractTileEntity implements ITic
|
||||
protected void unloadServer() {
|
||||
super.unloadServer();
|
||||
|
||||
virtualMachine.unload();
|
||||
virtualMachine.suspend();
|
||||
|
||||
// This is necessary in case some other controller found us before our controller
|
||||
// did its scan, which can happen because the scan can happen with a delay. In
|
||||
|
||||
@@ -81,7 +81,7 @@ public abstract class AbstractVirtualMachine implements VirtualMachine {
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public void unload() {
|
||||
public void suspend() {
|
||||
joinWorkerThread();
|
||||
state.vmAdapter.suspend();
|
||||
state.context.invalidate();
|
||||
@@ -202,7 +202,7 @@ public abstract class AbstractVirtualMachine implements VirtualMachine {
|
||||
|
||||
state.board.reset();
|
||||
state.rpcAdapter.reset();
|
||||
state.vmAdapter.unload();
|
||||
state.vmAdapter.unmount();
|
||||
|
||||
runner = null;
|
||||
}
|
||||
@@ -306,7 +306,7 @@ public abstract class AbstractVirtualMachine implements VirtualMachine {
|
||||
return;
|
||||
}
|
||||
|
||||
final VMDeviceLoadResult loadResult = state.vmAdapter.load();
|
||||
final VMDeviceLoadResult loadResult = state.vmAdapter.mount();
|
||||
if (!loadResult.wasSuccessful()) {
|
||||
if (loadResult.getErrorMessage() != null) {
|
||||
error(loadResult.getErrorMessage(), false);
|
||||
|
||||
@@ -34,7 +34,7 @@ public final class VMDeviceBusAdapter {
|
||||
baseAddressProvider = provider;
|
||||
}
|
||||
|
||||
public VMDeviceLoadResult load() {
|
||||
public VMDeviceLoadResult mount() {
|
||||
for (int i = 0; i < incompleteLoads.size(); i++) {
|
||||
final VMDevice device = incompleteLoads.get(i);
|
||||
|
||||
@@ -43,7 +43,7 @@ public final class VMDeviceBusAdapter {
|
||||
|
||||
deviceContexts.put(device, context);
|
||||
|
||||
final VMDeviceLoadResult result = device.load(context);
|
||||
final VMDeviceLoadResult result = device.mount(context);
|
||||
context.freeze();
|
||||
|
||||
if (!result.wasSuccessful()) {
|
||||
@@ -61,23 +61,20 @@ public final class VMDeviceBusAdapter {
|
||||
return VMDeviceLoadResult.success();
|
||||
}
|
||||
|
||||
public void unload() {
|
||||
public void unmount() {
|
||||
for (final VMDevice device : deviceContexts.keySet()) {
|
||||
device.unload();
|
||||
device.unmount();
|
||||
}
|
||||
|
||||
suspend();
|
||||
unload();
|
||||
}
|
||||
|
||||
public void suspend() {
|
||||
deviceContexts.forEach((device, context) -> {
|
||||
if (context != null) {
|
||||
context.invalidate();
|
||||
}
|
||||
});
|
||||
for (final VMDevice device : deviceContexts.keySet()) {
|
||||
device.suspend();
|
||||
}
|
||||
|
||||
incompleteLoads.clear();
|
||||
incompleteLoads.addAll(deviceContexts.keySet());
|
||||
unload();
|
||||
}
|
||||
|
||||
public void addDevices(final Collection<Device> devices) {
|
||||
@@ -100,7 +97,7 @@ public final class VMDeviceBusAdapter {
|
||||
if (device instanceof VMDevice) {
|
||||
final VMDevice vmDevice = (VMDevice) device;
|
||||
|
||||
vmDevice.unload();
|
||||
vmDevice.unmount();
|
||||
|
||||
final ManagedVMContext context = deviceContexts.remove(vmDevice);
|
||||
if (context != null) {
|
||||
@@ -111,4 +108,17 @@ public final class VMDeviceBusAdapter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private void unload() {
|
||||
deviceContexts.forEach((device, context) -> {
|
||||
if (context != null) {
|
||||
context.invalidate();
|
||||
}
|
||||
});
|
||||
|
||||
incompleteLoads.clear();
|
||||
incompleteLoads.addAll(deviceContexts.keySet());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,64 +63,64 @@ public final class VMDeviceTests {
|
||||
public void addedDevicesHaveLoadCalled() {
|
||||
final VMDevice device1 = mock(VMDevice.class);
|
||||
final VMDevice device2 = mock(VMDevice.class);
|
||||
when(device1.load(any())).thenReturn(VMDeviceLoadResult.success());
|
||||
when(device2.load(any())).thenReturn(VMDeviceLoadResult.success());
|
||||
when(device1.mount(any())).thenReturn(VMDeviceLoadResult.success());
|
||||
when(device2.mount(any())).thenReturn(VMDeviceLoadResult.success());
|
||||
|
||||
adapter.addDevices(Collections.singleton(device1));
|
||||
assertTrue(adapter.load().wasSuccessful());
|
||||
verify(device1).load(any());
|
||||
assertTrue(adapter.mount().wasSuccessful());
|
||||
verify(device1).mount(any());
|
||||
|
||||
adapter.addDevices(Collections.singleton(device2));
|
||||
assertTrue(adapter.load().wasSuccessful());
|
||||
assertTrue(adapter.mount().wasSuccessful());
|
||||
|
||||
verifyNoMoreInteractions(device1);
|
||||
verify(device2).load(any());
|
||||
verify(device2).mount(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removedDevicesHaveUnloadCalled() {
|
||||
final VMDevice device = mock(VMDevice.class);
|
||||
when(device.load(any())).thenReturn(VMDeviceLoadResult.success());
|
||||
when(device.mount(any())).thenReturn(VMDeviceLoadResult.success());
|
||||
|
||||
adapter.addDevices(Collections.singleton(device));
|
||||
assertTrue(adapter.load().wasSuccessful());
|
||||
assertTrue(adapter.mount().wasSuccessful());
|
||||
|
||||
adapter.removeDevices(Collections.singleton(device));
|
||||
verify(device).unload();
|
||||
verify(device).unmount();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void devicesHaveUnloadCalledOnGlobalUnload() {
|
||||
final VMDevice device = mock(VMDevice.class);
|
||||
when(device.load(any())).thenReturn(VMDeviceLoadResult.success());
|
||||
when(device.mount(any())).thenReturn(VMDeviceLoadResult.success());
|
||||
|
||||
adapter.addDevices(Collections.singleton(device));
|
||||
assertTrue(adapter.load().wasSuccessful());
|
||||
assertTrue(adapter.mount().wasSuccessful());
|
||||
|
||||
adapter.unload();
|
||||
verify(device).unload();
|
||||
adapter.unmount();
|
||||
verify(device).unmount();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void devicesHaveLoadCalledAfterGlobalUnload() {
|
||||
final VMDevice device = mock(VMDevice.class);
|
||||
when(device.load(any())).thenReturn(VMDeviceLoadResult.success());
|
||||
when(device.mount(any())).thenReturn(VMDeviceLoadResult.success());
|
||||
|
||||
adapter.addDevices(Collections.singleton(device));
|
||||
assertTrue(adapter.load().wasSuccessful());
|
||||
verify(device).load(any());
|
||||
assertTrue(adapter.mount().wasSuccessful());
|
||||
verify(device).mount(any());
|
||||
|
||||
adapter.unload();
|
||||
verify(device).unload();
|
||||
adapter.unmount();
|
||||
verify(device).unmount();
|
||||
|
||||
assertTrue(adapter.load().wasSuccessful());
|
||||
verify(device, times(2)).load(any());
|
||||
assertTrue(adapter.mount().wasSuccessful());
|
||||
verify(device, times(2)).mount(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deviceCanClaimInterrupts() {
|
||||
final VMDevice device = mock(VMDevice.class);
|
||||
when(device.load(any())).thenAnswer(invocation -> {
|
||||
when(device.mount(any())).thenAnswer(invocation -> {
|
||||
final VMContext context = invocation.getArgument(0);
|
||||
final OptionalInt interrupt = context.getInterruptAllocator().claimInterrupt();
|
||||
assertTrue(interrupt.isPresent());
|
||||
@@ -128,9 +128,9 @@ public final class VMDeviceTests {
|
||||
});
|
||||
|
||||
adapter.addDevices(Collections.singleton(device));
|
||||
assertTrue(adapter.load().wasSuccessful());
|
||||
assertTrue(adapter.mount().wasSuccessful());
|
||||
|
||||
verify(device).load(any());
|
||||
verify(device).mount(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -138,7 +138,7 @@ public final class VMDeviceTests {
|
||||
final int claimedInterrupt = 1;
|
||||
|
||||
final VMDevice device = mock(VMDevice.class);
|
||||
when(device.load(any())).thenAnswer(invocation -> {
|
||||
when(device.mount(any())).thenAnswer(invocation -> {
|
||||
final VMContext context = invocation.getArgument(0);
|
||||
final boolean result = context.getInterruptAllocator().claimInterrupt(claimedInterrupt);
|
||||
assertFalse(result);
|
||||
@@ -148,14 +148,14 @@ public final class VMDeviceTests {
|
||||
context.getInterruptAllocator().claimInterrupt(claimedInterrupt);
|
||||
|
||||
adapter.addDevices(Collections.singleton(device));
|
||||
assertTrue(adapter.load().wasSuccessful());
|
||||
assertTrue(adapter.mount().wasSuccessful());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deviceCanRaiseClaimedInterrupts() {
|
||||
final DeviceData deviceData = new DeviceData();
|
||||
final VMDevice device = mock(VMDevice.class);
|
||||
when(device.load(any())).thenAnswer(invocation -> {
|
||||
when(device.mount(any())).thenAnswer(invocation -> {
|
||||
final VMContext context = invocation.getArgument(0);
|
||||
final OptionalInt interrupt = context.getInterruptAllocator().claimInterrupt();
|
||||
assertTrue(interrupt.isPresent());
|
||||
@@ -167,7 +167,7 @@ public final class VMDeviceTests {
|
||||
});
|
||||
|
||||
adapter.addDevices(Collections.singleton(device));
|
||||
assertTrue(adapter.load().wasSuccessful());
|
||||
assertTrue(adapter.mount().wasSuccessful());
|
||||
|
||||
final int claimedInterruptMask = 1 << deviceData.interrupt;
|
||||
deviceData.context.getInterruptController().raiseInterrupts(claimedInterruptMask);
|
||||
@@ -179,13 +179,13 @@ public final class VMDeviceTests {
|
||||
public void devicesCannotRaiseUnclaimedInterrupts() {
|
||||
final DeviceData deviceData = new DeviceData();
|
||||
final VMDevice device = mock(VMDevice.class);
|
||||
when(device.load(any())).thenAnswer(invocation -> {
|
||||
when(device.mount(any())).thenAnswer(invocation -> {
|
||||
deviceData.context = invocation.getArgument(0);
|
||||
return VMDeviceLoadResult.success();
|
||||
});
|
||||
|
||||
adapter.addDevices(Collections.singleton(device));
|
||||
assertTrue(adapter.load().wasSuccessful());
|
||||
assertTrue(adapter.mount().wasSuccessful());
|
||||
|
||||
final int someInterruptMask = 0x1;
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
@@ -196,7 +196,7 @@ public final class VMDeviceTests {
|
||||
public void unloadLowersClaimedInterrupts() {
|
||||
final DeviceData deviceData = new DeviceData();
|
||||
final VMDevice device = mock(VMDevice.class);
|
||||
when(device.load(any())).thenAnswer(invocation -> {
|
||||
when(device.mount(any())).thenAnswer(invocation -> {
|
||||
final VMContext context = invocation.getArgument(0);
|
||||
final OptionalInt interrupt = context.getInterruptAllocator().claimInterrupt();
|
||||
assertTrue(interrupt.isPresent());
|
||||
@@ -208,14 +208,14 @@ public final class VMDeviceTests {
|
||||
});
|
||||
|
||||
adapter.addDevices(Collections.singleton(device));
|
||||
assertTrue(adapter.load().wasSuccessful());
|
||||
assertTrue(adapter.mount().wasSuccessful());
|
||||
|
||||
final int claimedInterruptMask = 1 << deviceData.interrupt;
|
||||
deviceData.context.getInterruptController().raiseInterrupts(claimedInterruptMask);
|
||||
|
||||
assertTrue((interruptController.getRaisedInterrupts() & claimedInterruptMask) != 0);
|
||||
|
||||
adapter.unload();
|
||||
adapter.unmount();
|
||||
|
||||
assertFalse((interruptController.getRaisedInterrupts() & claimedInterruptMask) != 0);
|
||||
}
|
||||
@@ -223,7 +223,7 @@ public final class VMDeviceTests {
|
||||
@Test
|
||||
public void devicesCannotAddToMemoryMapDirectly() {
|
||||
final VMDevice device = mock(VMDevice.class);
|
||||
when(device.load(any())).thenAnswer(invocation -> {
|
||||
when(device.mount(any())).thenAnswer(invocation -> {
|
||||
final VMContext context = invocation.getArgument(0);
|
||||
|
||||
assertThrows(UnsupportedOperationException.class, () ->
|
||||
@@ -233,14 +233,14 @@ public final class VMDeviceTests {
|
||||
});
|
||||
|
||||
adapter.addDevices(Collections.singleton(device));
|
||||
adapter.load();
|
||||
adapter.mount();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void devicesCanAddMemoryMappedDevices() {
|
||||
final DeviceData deviceData = new DeviceData();
|
||||
final VMDevice device = mock(VMDevice.class);
|
||||
when(device.load(any())).thenAnswer(invocation -> {
|
||||
when(device.mount(any())).thenAnswer(invocation -> {
|
||||
final VMContext context = invocation.getArgument(0);
|
||||
|
||||
deviceData.context = context;
|
||||
@@ -253,7 +253,7 @@ public final class VMDeviceTests {
|
||||
});
|
||||
|
||||
adapter.addDevices(Collections.singleton(device));
|
||||
assertTrue(adapter.load().wasSuccessful());
|
||||
assertTrue(adapter.mount().wasSuccessful());
|
||||
|
||||
assertTrue(deviceData.context.getMemoryMap().getMemoryRange(deviceData.device).isPresent());
|
||||
}
|
||||
@@ -262,7 +262,7 @@ public final class VMDeviceTests {
|
||||
public void addedDevicesGetRemovedOnUnload() {
|
||||
final DeviceData deviceData = new DeviceData();
|
||||
final VMDevice device = mock(VMDevice.class);
|
||||
when(device.load(any())).thenAnswer(invocation -> {
|
||||
when(device.mount(any())).thenAnswer(invocation -> {
|
||||
final VMContext context = invocation.getArgument(0);
|
||||
|
||||
deviceData.context = context;
|
||||
@@ -275,11 +275,11 @@ public final class VMDeviceTests {
|
||||
});
|
||||
|
||||
adapter.addDevices(Collections.singleton(device));
|
||||
assertTrue(adapter.load().wasSuccessful());
|
||||
assertTrue(adapter.mount().wasSuccessful());
|
||||
|
||||
assertTrue(deviceData.context.getMemoryMap().getMemoryRange(deviceData.device).isPresent());
|
||||
|
||||
adapter.unload();
|
||||
adapter.unmount();
|
||||
|
||||
assertFalse(deviceData.context.getMemoryMap().getMemoryRange(deviceData.device).isPresent());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user