package edu.purdue.scjtck.tck; import javax.realtime.ImmortalMemory; import javax.realtime.LTMemory; import javax.realtime.MemoryArea; import javax.realtime.RealtimeThread; import javax.realtime.ScopedMemory; import javax.safetycritical.MissionSequencer; import javax.safetycritical.PrivateMemory; /** * @author leizhao * * Assertions: * * - A scope may only be entered from the memory area in which it is * created; * * - Each application uses a global mission scope in the place of * immortal memory to hold global objects used during a mission; * * - In initialization phase and mission phase all objects are allocated * in mission memory; * * - Each schedulable object has its private scoped memory; * * - Object creation in mission scoped memory or immortal memory during * the mission phase is allowed; * * - PrivateMemory is based on LTMemory * * - Deep nested private memory is supported; * * - MissionMemory is ScopedMemory; */ public class TestMemory501 extends TestCase { public MissionSequencer getSequencer() { /* * FIXME: I don't think there is a clear description of the place where * a PrivateMemory can be created. They say one can create PrivateMemory * during (mission) initialization or during mission phase, but do not * explicitly prohibit the creation in other place, e.g ImmortalMemory. * (RI does so though via throw exception, see PrivateMemory.java) */ /* * PrivateMemory is not accessible to the user. Memory areas shall not * be created by the user. */ // try { // new PrivateMemory(5); // fail("PrivateMemory illegally created in " // + RealtimeThread.getCurrentMemoryArea()); // } catch (Throwable t) { // // PrivateMemory is not supposed to be created out side // // MissionMemory or PrivateMemory // } return new GeneralSingleMissionSequencer(new GeneralMission() { private int _depth; @Override public void initialize() { final MemoryArea missionMem = RealtimeThread .getCurrentMemoryArea(); if (!(missionMem instanceof ScopedMemory)) { fail("Mission memory is not instance of ScopedMemory"); } new GeneralPeriodicEventHandler() { @Override public void handleAsyncEvent() { MemoryArea privateMem = RealtimeThread .getCurrentMemoryArea(); if (!(privateMem instanceof PrivateMemory)) fail("Schedulable objects not run in private memory"); if (!(privateMem instanceof ScopedMemory)) fail("Private memory is not instance of ScopedMemory"); if (!(privateMem instanceof LTMemory)) fail("Private memory is not instance of LTMemory"); _depth = 0; new PrivateMemory(5000).enter(new Runnable() { public void run() { final MissionManager mngrL1 = ((PrivateMemory) RealtimeThread .getCurrentMemoryArea()).getManager(); new PrivateMemory(5000).enter(new Runnable() { public void run() { MissionManager mngrL2 = ((PrivateMemory) RealtimeThread .getCurrentMemoryArea()) .getManager(); if (!mngrL1.equals(mngrL2)) fail("Error occured in PrivateMemory.getManager()"); _depth++; } }); _depth++; if (_depth != 2) fail("Unable to enter nested private memory"); } }); } }; /* * Object creation in mission scoped memory or immortal memory * during the mission phase is allowed */ new GeneralPeriodicEventHandler() { @Override public void handleAsyncEvent() { try { missionMem.newInstance(Object.class); } catch (Throwable e) { fail("Error occured during object creation in mission memory during mission phase"); } try { ImmortalMemory.instance().newInstance(Object.class); } catch (Throwable e) { fail("Error occured during object creation in immortal memory during mission phase"); } } }; /* * A scope may only be entered from the memory area in which it * is created */ final PrivateMemory scopeL1 = new PrivateMemory(5000); final PrivateMemory scopeL2 = new PrivateMemory(5000); new GeneralPeriodicEventHandler() { @Override public void handleAsyncEvent() { scopeL1.enter(new Runnable() { public void run() { try { scopeL2.enter(new Runnable() { public void run() { fail("Private memory not entered from its parent scope"); } }); } catch (Throwable t) { /* * scopeL2 is not allowed to be entered in * scopeL1; there should be some exceptions * thrown here */ } } }); } }; /* * A mission global object, which should be able to be touched * by PEHs */ final int nValueReaders = 3; final int value = 42; final Integer missionGlobalNum = new Integer(value); for (int i = 0; i < nValueReaders; i++) new GeneralPeriodicEventHandler() { @Override public void handleAsyncEvent() { if (missionGlobalNum.intValue() != value) { fail("Mission global object inaccessible or incorrect"); } } }; new Terminator(); } }); } @Override public long immortalMemorySize() { // TODO Auto-generated method stub return 0; } @Override protected String getArgs() { // TODO Auto-generated method stub return null; } }