├── .gitignore ├── License ├── README.md ├── bench ├── data │ ├── erlang_kilim_ping_pong.xls │ ├── erlang_kilim_task_creation.xls │ └── kilim_sunfire_pingpong.xls ├── erlang │ ├── bigpingpong.erl │ ├── numprocs.erl │ ├── pingpong.erl │ └── taskstart.erl ├── haskell │ └── Chain.hs ├── kilim │ └── bench │ │ ├── BigPingPong.java │ │ ├── Chain.java │ │ ├── Ex_vs_Ret.java │ │ ├── Jetlang.java │ │ ├── LotsOfTasks.java │ │ ├── PingPong.java │ │ ├── Rec.java │ │ ├── Ring.java │ │ ├── Sleep.java │ │ ├── Stopwatch.java │ │ ├── ThreadBench.java │ │ ├── ThreadPipePingPong.java │ │ ├── Unwind.java │ │ └── rmi │ │ └── RMI.java └── scala │ ├── BigPingPong.scala │ ├── Msg.scala │ ├── PingPongEx.scala │ └── oBigPingPong.scala ├── build.xml ├── demos ├── .gitignore ├── battle │ ├── pom.xml │ ├── pom11.xml │ ├── pom12.xml │ ├── pom13.xml │ ├── pom9.xml │ └── src │ │ └── main │ │ └── java │ │ └── kilim │ │ └── demo │ │ └── Battle.java ├── battle10 │ ├── pom-weave.xml │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── kilim │ │ └── demo │ │ ├── Battle.java │ │ └── HelloWorld.java ├── invoke │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── kilim │ │ └── demo │ │ ├── CodeA.java │ │ ├── CodeB.java │ │ └── Invoke.java ├── java11 │ ├── README.md │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── kilim │ │ └── demo │ │ ├── LambdaLoader.java │ │ └── LambdaToFile.java ├── java7 │ ├── pom.xml │ ├── readme.txt │ └── src │ │ └── main │ │ └── java │ │ └── kilim │ │ └── demo │ │ └── Battle.java ├── jetty │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── kilim │ │ └── demo │ │ ├── KilimAsyncIO.java │ │ ├── KilimHandler.java │ │ └── KilimServlet.java ├── jetty7 │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── kilim │ │ └── demo │ │ └── KilimHandler7.java ├── jshell │ ├── README.md │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── Kshell.java │ │ └── resources │ │ └── META-INF │ │ └── services │ │ └── jdk.jshell.spi.ExecutionControlProvider └── poms │ ├── pom-jetty.xml │ ├── pom.xml │ ├── pom10-weave.xml │ ├── pom10.xml │ ├── pom11.xml │ ├── pom12.xml │ ├── pom13.xml │ ├── pom7-jetty.xml │ ├── pom7.xml │ └── pom9.xml ├── docs ├── IFAQ.txt ├── archive │ ├── build.sh │ └── test.sh ├── demos.md ├── history.txt ├── internals │ ├── fiber_states.graffle │ ├── fiber_states.pdf │ ├── task_states.graffle │ ├── task_states.pdf │ └── task_states.txt ├── kilim_ecoop08.pdf ├── limitations.md ├── manual.html ├── maven_plugin │ └── README.md ├── style.css └── thread_of_ones_own.pdf ├── pom.xml ├── src └── kilim │ ├── AffineScheduler.java │ ├── Cell.java │ ├── Constants.java │ ├── Continuation.java │ ├── Event.java │ ├── EventPublisher.java │ ├── EventSubscriber.java │ ├── ExitMsg.java │ ├── Fiber.java │ ├── ForkJoinScheduler.java │ ├── Generator.java │ ├── KilimClassLoader.java │ ├── KilimException.java │ ├── Mailbox.java │ ├── MailboxMPSC.java │ ├── MailboxSPSC.java │ ├── NotPausable.java │ ├── Pausable.java │ ├── PauseReason.java │ ├── ReentrantLock.java │ ├── RingQueue.java │ ├── Scheduler.java │ ├── ServletHandler.java │ ├── ShutdownException.java │ ├── State.java │ ├── Task.java │ ├── TaskDoneReason.java │ ├── TaskGroup.java │ ├── WeavingClassLoader.java │ ├── YieldReason.java │ ├── analysis │ ├── BBList.java │ ├── BasicBlock.java │ ├── CallWeaver.java │ ├── ClassFlow.java │ ├── ClassInfo.java │ ├── ClassWeaver.java │ ├── ClassWriter.java │ ├── FileLister.java │ ├── Frame.java │ ├── Handler.java │ ├── IncompatibleTypesException.java │ ├── KilimContext.java │ ├── MethodFlow.java │ ├── MethodWeaver.java │ ├── NopInsn.java │ ├── Range.java │ ├── SAMweaver.java │ ├── TypeDesc.java │ ├── Usage.java │ ├── Utils.java │ └── Value.java │ ├── bench │ ├── concurrent │ ├── MPSCQueue.java │ ├── PaddedEventSubscriber.java │ ├── SPSCQueue.java │ ├── UnsafeAccess.java │ ├── VolatileBoolean.java │ ├── VolatileLongCell.java │ └── VolatileReferenceCell.java │ ├── examples │ ├── Chain.java │ ├── Ex.java │ ├── Fib.java │ ├── Group.java │ ├── HeapBlast.java │ ├── HttpFileServer.java │ ├── PerfTest.java │ ├── Ping.java │ ├── Pure.java │ ├── Reflect.java │ ├── SimpleHttpServer.java │ ├── SimpleTask.java │ ├── SimpleTask2.java │ ├── Spawn.java │ ├── TimedTask.java │ ├── TimerBlast.java │ ├── TimerBlast2.java │ ├── Tree.java │ ├── Userdata.java │ └── Xorshift.java │ ├── http │ ├── HttpMsg.java │ ├── HttpRequest.java │ ├── HttpRequestParser.java │ ├── HttpRequestParser.rl │ ├── HttpResponse.java │ ├── HttpServer.java │ ├── HttpSession.java │ ├── IntList.java │ ├── KeyValues.java │ ├── KilimMvc.java │ ├── MimeTypes.java │ └── Utils.java │ ├── mirrors │ ├── CachedClassMirrors.java │ ├── ClassMirrorNotFoundException.java │ └── Detector.java │ ├── nio │ ├── EndPoint.java │ ├── ExposedBais.java │ ├── ExposedBaos.java │ ├── NioSelectorScheduler.java │ ├── SessionTask.java │ └── SockEvent.java │ ├── plugins │ └── KilimMavenPlugin.java │ ├── support │ └── JettyHandler.java │ ├── timerservice │ ├── Timer.java │ ├── TimerPriorityHeap.java │ └── TimerService.java │ └── tools │ ├── Agent.java │ ├── Asm.java │ ├── DumpClass.java │ ├── FlowAnalyzer.java │ ├── Javac.java │ ├── Kilim.java │ ├── P.java │ └── Weaver.java ├── test └── kilim │ └── test │ ├── AllNotWoven.java │ ├── AllWoven.java │ ├── Base.java │ ├── TaskTestClassLoader.java │ ├── TestAbstractExtends.java │ ├── TestBasicBlock.java │ ├── TestClassInfo.java │ ├── TestDynamicWeaver.java │ ├── TestExprs.java │ ├── TestFlow.java │ ├── TestFrame.java │ ├── TestGenerics.java │ ├── TestHTTP.java │ ├── TestIO.java │ ├── TestInterface.java │ ├── TestInvalidPausables.java │ ├── TestJSR.java │ ├── TestLambda.java │ ├── TestLock.java │ ├── TestMailbox.java │ ├── TestPrefThread.java │ ├── TestRing.java │ ├── TestTypeDesc.java │ ├── TestUsage.java │ ├── TestValue.java │ ├── TestYield.java │ ├── TestYieldExceptions.java │ ├── TestYieldJSR.java │ └── ex │ ├── ExA.java │ ├── ExB.java │ ├── ExBasicBlock.java │ ├── ExC.java │ ├── ExCatch.java │ ├── ExD.java │ ├── ExEx.java │ ├── ExException.java │ ├── ExExpr.java │ ├── ExFlow.java │ ├── ExFrame.java │ ├── ExGenerics.java │ ├── ExInterfaceGeneric.java │ ├── ExInterfaceGenericTask.java │ ├── ExInterfaceImpl.java │ ├── ExInvalid.java │ ├── ExInvalidSynchronized.java │ ├── ExJSR.j │ ├── ExLoop.java │ ├── ExPausable.java │ ├── ExTaskArgTypes.java │ ├── ExYieldBase.java │ ├── ExYieldConstants.java │ ├── ExYieldDups.java │ ├── ExYieldStack.java │ ├── ExYieldSub.j │ └── TaskStatusCB.java └── testing ├── README.md ├── java10 ├── .gitignore ├── pom-test.xml ├── pom10.xml ├── src └── test10.sh ├── pom-test.xml ├── pom.xml ├── pom10.xml ├── pom11.xml ├── pom12.xml ├── pom13.xml ├── pom7.xml ├── pom8.xml ├── pom9.xml ├── src └── testing.sh /.gitignore: -------------------------------------------------------------------------------- 1 | /plugins/maven/target/ 2 | /target 3 | /libs 4 | /demos/jetty/target/ 5 | /nbactions.xml 6 | /demos/jetty/nb-configuration.xml 7 | /nb-configuration.xml 8 | /plugins/maven/nb-configuration.xml 9 | /testing/target/ -------------------------------------------------------------------------------- /License: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright 2006-2014 Sriram Srinivasan (kilim@malhar.net) 4 | Copyright 2016-2018 nqzero 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining 7 | a copy of this software and associated documentation files (the 8 | "Software"), to deal in the Software without restriction, including 9 | without limitation the rights to use, copy, modify, merge, publish, 10 | distribute, sublicense, and/or sell copies of the Software, and to 11 | permit persons to whom the Software is furnished to do so, subject to 12 | the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be 15 | included in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | 25 | -------------------------------------------------------------------------------- /bench/data/erlang_kilim_ping_pong.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nqzero/kilim/16bc45e3a07ce074947722618982e90747dcb987/bench/data/erlang_kilim_ping_pong.xls -------------------------------------------------------------------------------- /bench/data/erlang_kilim_task_creation.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nqzero/kilim/16bc45e3a07ce074947722618982e90747dcb987/bench/data/erlang_kilim_task_creation.xls -------------------------------------------------------------------------------- /bench/data/kilim_sunfire_pingpong.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nqzero/kilim/16bc45e3a07ce074947722618982e90747dcb987/bench/data/kilim_sunfire_pingpong.xls -------------------------------------------------------------------------------- /bench/erlang/bigpingpong.erl: -------------------------------------------------------------------------------- 1 | -module(bigpingpong). 2 | -export([bench/1, start/1, recv/2]). 3 | 4 | % Create N procs. Each proc sends a message to every other (n-1), 5 | % and waits for n-1 msgs from the others, before signalling 6 | % to a collector proc that it is done. Elapsed time is measured. 7 | % N procs => Num Msgs = n(n+1). (Including extra msg initially 8 | % to each proc to start. 9 | 10 | bench(N) -> bench(10, N). % Run benchmark 10 times 11 | 12 | bench(0, _) -> done; 13 | bench(M, N) -> 14 | start(N), 15 | % Wait a little for possible background cleanup to occur 16 | receive 17 | after 1000 18 | -> done 19 | end, 20 | bench(M-1, N). 21 | 22 | start(NumProcesses) -> 23 | statistics(runtime), 24 | Pids = spawnN(NumProcesses, NumProcesses, self(), []), 25 | lists:foreach( 26 | fun(Pid) -> 27 | Pid ! {start, Pids} 28 | end, 29 | Pids), 30 | wait(NumProcesses, NumProcesses). 31 | 32 | wait(0, _) -> %wait(0, OrigN) -> 33 | {_, T} = statistics(runtime), 34 | % if T == 0 -> 35 | % io:format("Elapsed: ~p ms ~n", [T]); 36 | % true -> 37 | % io:format("Elapsed: ~p ms, ~p tasks/ms ~n", [T, OrigN/T]) 38 | % end; 39 | io:format("~p~n", [T]); 40 | 41 | wait(N, OrigN) -> 42 | receive 43 | done -> 44 | wait(N-1, OrigN) 45 | end. 46 | 47 | 48 | % Spawn N procs and return list of pids 49 | spawnN(0, _, _, ListAlreadySpawned) -> ListAlreadySpawned; 50 | spawnN(N, OrigN, MainPid, ListAlreadySpawned) -> 51 | Pid = spawn(bigpingpong, recv, [MainPid, OrigN]), 52 | spawnN(N-1, OrigN, MainPid, [Pid|ListAlreadySpawned]). 53 | 54 | % Rcv 55 | recv(_, 1) -> done; % Done after n-1 msgs 56 | recv(MainPid, OrigN) -> 57 | receive 58 | {start, Pids} -> 59 | lists:foreach( 60 | fun(E) -> 61 | if 62 | % Skip self 63 | not (E == self()) -> 64 | E ! ping; 65 | true -> pass 66 | end 67 | end, 68 | Pids), 69 | MainPid ! done, 70 | recv(MainPid, OrigN); 71 | 72 | ping -> 73 | $ wait for n-1 msgs 74 | recv(MainPid, OrigN-1) 75 | end. 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /bench/erlang/numprocs.erl: -------------------------------------------------------------------------------- 1 | -module(numprocs). 2 | -export([bbench/1, bench/1, bench/2, start/1, start/2, recv/1]). 3 | 4 | 5 | % create N processes, wait for them to send a msg and die. 6 | % bench repeats this experiments a few times 7 | bench(N) -> bench(10, N). 8 | 9 | 10 | % spawn N processes that block. Measure time taken to spawn. Not 11 | % a good round-trip test. 12 | % bbench repeats this experiments a few times 13 | bbench(N) -> bbench(10, N). 14 | 15 | %====================================================================== 16 | 17 | bench(0,_) -> done; 18 | bench(M,N) -> 19 | start(N), 20 | % Wait a little for possible background cleanup to occur 21 | receive 22 | after 1000 23 | -> done 24 | end, 25 | bench(M-1, N). 26 | 27 | bbench(0, _) -> done; 28 | bbench(M, N) -> 29 | start(N, block), 30 | receive 31 | after 1000 -> done 32 | end, 33 | bbench(M-1, N). 34 | 35 | start(N) -> 36 | statistics(runtime), 37 | %io:format("spawning ~p procs~n", [N]), 38 | spawnN(N, self()), 39 | %io:format("waiting for them to finish~n"), 40 | wait(N, N). 41 | 42 | start(N, block) -> 43 | statistics(runtime), 44 | spawnN(N, nil), 45 | {_, T} = statistics(runtime), 46 | if T == 0 -> 47 | %io:format("Elapsed: ~p ms ~n", [T]); 48 | io:format("~p~n", [T]); 49 | true -> 50 | %io:format("Elapsed: ~p ms, ~p tasks/ms ~n", [T, N/T]) 51 | io:format("~p~n", [T]) 52 | end. 53 | 54 | wait(0, _) -> %wait(0, Total) -> 55 | {_, T} = statistics(runtime), 56 | if T == 0 -> 57 | %io:format("Elapsed: ~p ms ~n", [T]); 58 | io:format("~p~n", [T]); 59 | true -> 60 | %io:format("Elapsed: ~p ms, ~p tasks/ms ~n", [T, Total/T]) 61 | io:format("~p~n", [T]) 62 | end; 63 | wait(N, Total) -> 64 | receive 65 | done -> 66 | wait(N-1, Total) 67 | end. 68 | 69 | 70 | spawnN(0, _) -> done; 71 | spawnN(N, Main) -> 72 | % if (N rem 50000 == 0) -> 73 | % io:format("#Procs: ~p ~n", [N]); 74 | % true -> true 75 | % end, 76 | spawn(numprocs, recv, [Main]), 77 | spawnN(N-1, Main). 78 | 79 | recv(Main) -> 80 | if is_pid(Main) -> 81 | Main ! done; 82 | true -> 83 | receive 84 | hello -> recv(Main) 85 | end 86 | end. 87 | -------------------------------------------------------------------------------- /bench/erlang/pingpong.erl: -------------------------------------------------------------------------------- 1 | -module(pingpong). 2 | -export([start/0, ping/3, pong/0]). 3 | 4 | start() -> 5 | Pong = spawn(pingpong, pong, []), 6 | spawn(pingpong, ping, [Pong, erlang:now(), 100000]). 7 | 8 | ping(_, StartTime, 0) -> 9 | io:format("Elapsed: ~p~n", [timer:now_diff(erlang:now(), StartTime)]); 10 | 11 | ping(Pong, StartTime, N) -> 12 | %io:format("ping ~p~n", [N]), 13 | Pong ! {ping, self()}, 14 | receive 15 | pong -> 16 | ping(Pong, StartTime, N-1) 17 | end. 18 | 19 | 20 | pong() -> 21 | receive 22 | {ping, Ping} -> 23 | %io:format("Received ping~n"), 24 | Ping ! pong, 25 | pong() 26 | end. 27 | 28 | -------------------------------------------------------------------------------- /bench/erlang/taskstart.erl: -------------------------------------------------------------------------------- 1 | -module(taskstart). 2 | -export([start/0, startRound/1, launch/1]). 3 | 4 | start() -> 5 | Reporter = spawn(taskstart, startRound, [10]), 6 | register(reporter, Reporter). 7 | 8 | %--------------------------------------------------------------------- 9 | % Reporter 10 | % Spawns a ring in each of n rounds, and waits for the ring 11 | % to signal completion. 12 | %--------------------------------------------------------------------- 13 | startRound(0)-> 14 | erlang:halt(); 15 | 16 | startRound(N)-> 17 | StartTime = erlang:now(), 18 | spawn(taskstart, launch, [100000]), 19 | receive 20 | EndTime -> 21 | io:format("~p ~p~n", [N, timer:now_diff(EndTime, StartTime)]) 22 | end, 23 | startRound(N-1). 24 | 25 | %--------------------------------------------------------------------- 26 | %Ring 27 | % Each process m spawns process m-1. The last process sends the 28 | % current time to the reporter. 29 | %--------------------------------------------------------------------- 30 | 31 | launch(0) -> 32 | EndTime = erlang:now(), 33 | whereis(reporter) ! EndTime; 34 | 35 | launch(M) -> 36 | spawn(taskstart, launch, [M-1]). 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /bench/haskell/Chain.hs: -------------------------------------------------------------------------------- 1 | -- Set up n threads in a chain. Each thread retrieves from its MVar and 2 | -- dumps that value on the next MVar 3 | 4 | -- This benchmark adapted from Bryan O'Sullivan's blog. The difference is 5 | -- that the threads are each given their own MVar to reduce contention. 6 | 7 | -- Compile with ghc -O2 --make Chain.hs 8 | -- Run ./Chain 100000 9 | -- Compare to java kilim.bench.Chain -ntasks 100000 -nmsgs 1 10 | 11 | module Main where 12 | 13 | import Control.Applicative 14 | import Control.Concurrent.MVar 15 | import Control.Concurrent 16 | import System.Environment 17 | import Data.Time 18 | 19 | main = do 20 | mv <- newEmptyMVar 21 | start <- getCurrentTime 22 | lastmv <- (loop mv =<< read . head <$> getArgs) 23 | end <- getCurrentTime 24 | putStrLn $ "creation time: " ++ show (diffUTCTime end start) 25 | putMVar mv 0 26 | lastnum <- takeMVar lastmv 27 | fin <- getCurrentTime 28 | putStrLn $ "message time: " ++ show (diffUTCTime fin end) 29 | putStrLn $ "Threads: " ++ show lastnum 30 | 31 | loop :: MVar Int -> Int -> IO (MVar Int) 32 | loop mv n | n <= 0 = return mv 33 | | otherwise = do 34 | nextmv <- newEmptyMVar 35 | forkIO $ do 36 | m <- takeMVar mv 37 | putMVar nextmv $! m+1 38 | loop nextmv $! n-1 39 | 40 | -------------------------------------------------------------------------------- /bench/kilim/bench/Ex_vs_Ret.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.bench; 8 | 9 | public class Ex_vs_Ret { 10 | 11 | /** 12 | * @param args 13 | */ 14 | public static void main(String[] args) { 15 | final int ntimes = 1000000; 16 | final int depth = 10; 17 | 18 | // JIT Warmup =========================================== 19 | for (int i = 0; i < 1000; i++) ret(depth); 20 | for (int i = 0; i < 1000; i++) { 21 | try { 22 | ex(depth); 23 | } catch (FastEx ignore) {} 24 | } 25 | 26 | long start = System.currentTimeMillis(); 27 | for (int i = 0; i < ntimes; i++) { 28 | ret(depth); 29 | } 30 | long elapsed = System.currentTimeMillis() - start; 31 | System.out.println("Iterations = : " +ntimes + ", stack depth = " + depth); 32 | System.out.println("ret ms: " + elapsed); 33 | 34 | start = System.currentTimeMillis(); 35 | for (int i = 0; i < ntimes; i++) { 36 | try { 37 | ex(depth); 38 | } catch (FastEx fe) {} 39 | } 40 | elapsed = System.currentTimeMillis() - start; 41 | System.out.println("ex : " + elapsed); 42 | } 43 | 44 | static void ret(int depth) { 45 | if (depth != 0) { 46 | ret(depth-1); 47 | } 48 | } 49 | 50 | static void ex(int depth) throws FastEx { 51 | if (depth == 0) { 52 | throw new FastEx(); 53 | } 54 | ex(depth-1); 55 | } 56 | } 57 | 58 | final class FastEx extends Throwable { 59 | private static final long serialVersionUID = 1L; // Just suppressing warnings. 60 | 61 | @Override 62 | public synchronized Throwable fillInStackTrace() { 63 | return null; // The most time consuming part of throwing an exception. 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /bench/kilim/bench/Jetlang.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.bench; 8 | import kilim.Mailbox; 9 | import kilim.Pausable; 10 | import kilim.Task; 11 | /** 12 | * Compare this to Jetlang's PerfMain tests 13 | * See http://code.google.com/p/jetlang/ 14 | */ 15 | public class Jetlang extends Task { 16 | 17 | /* limit number of msgs in mailbox */ 18 | static Mailbox mb = new Mailbox(1000,1000); 19 | final static int max = 5000000; 20 | 21 | public static void main(String args[]) throws Exception { 22 | Stopwatch s = new Stopwatch(); 23 | s.tick(); 24 | 25 | Task t = new Jetlang().start(); 26 | new Publisher().start(); 27 | t.joinb(); // wait for receiver to finish 28 | 29 | s.tickPrint(max+1); // same number of iterations as jetlang's tests. 30 | Task.idledown(); 31 | } 32 | 33 | public void execute() throws Pausable { 34 | while (true) { 35 | int i = mb.get(); 36 | if (i == max) { 37 | break; 38 | } 39 | } 40 | } 41 | 42 | static class Publisher extends Task { 43 | public void execute() throws Pausable { 44 | for (int i = 0; i <= max; i++) { 45 | mb.put(i); 46 | } 47 | } 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /bench/kilim/bench/Rec.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.bench; 8 | 9 | import kilim.*; 10 | 11 | public class Rec extends Task { 12 | static boolean pause = false; 13 | static boolean pausable = false; 14 | /** 15 | * benchmark recursion 16 | * @param args the number of passes and the depth of each pass, both optional 17 | */ 18 | public static void main(String[] args) throws Exception { 19 | int n = args.length < 1 ? 1000000 : Integer.parseInt(args[0]); 20 | int d = args.length < 2 ? 100 : Integer.parseInt(args[1]); 21 | 22 | pausable = true; 23 | 24 | pause = true; 25 | testCont(new Rec(5,5)); 26 | long tpause = testCont(new Rec(n, d)); 27 | 28 | pause = false; 29 | testCont(new Rec(5,5)); 30 | long tnopause = testCont(new Rec(n, d)); 31 | 32 | pausable = false; 33 | testCont(new Rec(5, 5)); 34 | long tbase = testCont(new Rec(n, d)); 35 | System.out.println(n + " " + tbase + " " + tnopause + " " + tpause); 36 | } 37 | 38 | public static long testCont(Rec ex) throws NotPausable, Exception { 39 | long start = System.currentTimeMillis(); 40 | if (pausable) { 41 | Fiber f = new Fiber(ex); 42 | while (true) { 43 | ex.execute(f.begin()); 44 | if (f.end()) break; 45 | } 46 | } else { 47 | ex.noPauseRun(); 48 | } 49 | return (System.currentTimeMillis() - start); 50 | } 51 | 52 | 53 | int n; 54 | int depth; 55 | public Rec(int an, int aDepth) { 56 | n = an; 57 | depth = aDepth; 58 | } 59 | 60 | public void execute() throws Pausable { 61 | for (int i = 0; i < n; i++) { 62 | rec(depth, "foo"); 63 | } 64 | } 65 | 66 | public void noPauseRun() { 67 | for (int i = 0; i < n; i++) { 68 | recNoPause(depth, "foo"); 69 | } 70 | } 71 | 72 | private void rec(int d, String s) throws Pausable { 73 | if (d == 1) { 74 | if (pause) { 75 | Task.yield(); 76 | } 77 | return; 78 | } 79 | rec(d-1, s); 80 | } 81 | 82 | private void recNoPause(int d, String s) { 83 | if (d == 1) { 84 | return; 85 | } 86 | recNoPause(d-1, s); 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /bench/kilim/bench/Ring.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.bench; 8 | 9 | import kilim.*; 10 | 11 | public class Ring extends Task { 12 | Mailbox mb; 13 | Mailbox prev; 14 | int times; // num times already gone around. When 0, won't pass it on. 15 | int num; // this task's number 16 | 17 | public static boolean logging = false; 18 | static long startTime; 19 | public static void main(String[] args) { 20 | int n = 10; // num elements in ring. 21 | int t = 100000; // num times around ring 22 | try { 23 | for (int i = 0; i < args.length; i++) { 24 | String arg = args[i]; 25 | if (arg.equals("-n")) { 26 | n = Integer.parseInt(args[++i]); 27 | } else if (arg.equals("-t")) { 28 | t = Integer.parseInt(args[++i]); 29 | } else if (arg.equals("-l")) { 30 | logging = true; 31 | } 32 | } 33 | } 34 | catch (NumberFormatException e) { 35 | System.err.println("Integer argument expected"); 36 | } 37 | if (logging) System.out.println("Started"); 38 | Mailbox mb = new Mailbox(); 39 | Mailbox startmb = mb; 40 | Ring r = new Ring(mb, null, 0, t); 41 | r.start(); 42 | Ring start = r; 43 | Mailbox prevmb = mb; 44 | for (int i = 1; i < n; i++) { 45 | mb = new Mailbox(); 46 | new Ring(mb, prevmb, i, t).start(); 47 | prevmb = mb; 48 | } 49 | start.prev = prevmb; 50 | startTime = System.currentTimeMillis(); 51 | startmb.putnb("ring"); 52 | } 53 | 54 | public Ring(Mailbox amb, Mailbox prevms,int anum, int atimes) { 55 | mb = amb; 56 | num = anum; 57 | times = atimes; 58 | prev = prevms; 59 | if (logging) { 60 | System.out.println("Proc# " + anum); 61 | } 62 | } 63 | 64 | public void execute() throws Pausable { 65 | while (true) { 66 | String m = mb.get(); 67 | if (logging) 68 | System.out.println(" Proc # " + num + ", iters left = " + times); 69 | if (--times == 0) { 70 | if (num == 1) { // last process 71 | long elapsedTime = System.currentTimeMillis() - startTime; 72 | System.out.println("Elapsed time: " + elapsedTime + " ms"); 73 | System.exit(0); 74 | } 75 | } 76 | prev.put(m); 77 | } 78 | } 79 | } 80 | 81 | 82 | -------------------------------------------------------------------------------- /bench/kilim/bench/Stopwatch.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.bench; 8 | 9 | public class Stopwatch { 10 | long lastTickMillis = System.currentTimeMillis(); 11 | long lastElapsedMillis = 0; 12 | int multiplier = 1; // see reportMicros 13 | String unit = " ms"; 14 | String name = ""; 15 | 16 | 17 | public Stopwatch() {tick();} 18 | public Stopwatch(String nm) {name = nm; tick();} 19 | 20 | /** 21 | * @return the diff in millis from the last tick. Both tick and elapsed times are 22 | * kept in millis 23 | */ 24 | public long tick() { 25 | long l = lastTickMillis; 26 | lastTickMillis = System.currentTimeMillis(); 27 | lastElapsedMillis = lastTickMillis - l; 28 | return lastElapsedMillis; 29 | } 30 | 31 | /** 32 | * Report in micros or millis 33 | */ 34 | public void reportMicros() {multiplier = 1000; unit = " micros";} 35 | public void reportMillis() {multiplier = 1; unit = " ms";} 36 | 37 | public long timePerIter(int iters) { 38 | return iters == 0? 0 : lastElapsedMillis*multiplier/iters; 39 | } 40 | 41 | long itersPerTime(int iters) { 42 | return lastElapsedMillis == 0 ? iters : iters/(lastElapsedMillis*multiplier); 43 | } 44 | 45 | public String toString() { 46 | return name + ": elapsed: " + (lastElapsedMillis * multiplier) + " " + unit; 47 | } 48 | 49 | public String toString(int iters) { 50 | return name + " elapsed: " + (lastElapsedMillis * multiplier) + 51 | unit +", iters = " + iters + 52 | ", " + unit + "/iter = " + timePerIter(iters) + 53 | ", iters/" + unit + " = " + itersPerTime(iters); 54 | } 55 | 56 | public void print() {System.out.println(this);} 57 | 58 | public void print(int iters) { System.out.println(this.toString(iters));} 59 | 60 | public void tickPrint() {tick(); print();} 61 | 62 | public void tickPrint(int iters) {tick(); print(iters);} 63 | } -------------------------------------------------------------------------------- /bench/kilim/bench/ThreadPipePingPong.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.bench; 8 | 9 | import java.io.PipedInputStream; 10 | import java.io.PipedOutputStream; 11 | 12 | 13 | // Create two threads, have a message ping pong between them using pipes. 14 | public class ThreadPipePingPong { 15 | public static void main(String args[]) throws Exception { 16 | int ntimes = args.length == 0 ? 1000 : Integer.parseInt(args[0]); 17 | PipedInputStream pi_in = new PipedInputStream(); 18 | PipedOutputStream pi_out = new PipedOutputStream(); 19 | PipedInputStream po_in = new PipedInputStream(pi_out); 20 | PipedOutputStream po_out = new PipedOutputStream(pi_in); 21 | 22 | PongThread po = new PongThread(po_in, po_out); 23 | PingThread pi = new PingThread(ntimes, pi_in, pi_out); 24 | po.start(); 25 | pi.start(); 26 | } 27 | } 28 | 29 | class PingThread extends Thread { 30 | int ntimes; 31 | PipedInputStream in; 32 | PipedOutputStream out; 33 | PingThread(int n, PipedInputStream i, PipedOutputStream o) { 34 | ntimes = n; 35 | in = i; 36 | out = o; 37 | } 38 | public void run() { 39 | try { 40 | long begin = System.currentTimeMillis(); 41 | for (int i = 0; i < ntimes; i++) { 42 | out.write(100); out.flush(); //ping 43 | in.read(); // wait for pong 44 | } 45 | System.out.println("Elapsed (" + ntimes + " iters) : " + 46 | (System.currentTimeMillis() - begin) + " millis"); 47 | System.exit(0); 48 | } catch (Exception e) { 49 | e.printStackTrace(); 50 | } 51 | } 52 | } 53 | 54 | class PongThread extends Thread { 55 | PipedInputStream in; 56 | PipedOutputStream out; 57 | 58 | PongThread(PipedInputStream i, PipedOutputStream o) { 59 | in = i; 60 | out = o; 61 | } 62 | public void run() { 63 | try { 64 | while (true) { 65 | in.read(); 66 | out.write(200); out.flush(); 67 | } 68 | } catch (Exception e) { 69 | e.printStackTrace(); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /bench/kilim/bench/rmi/RMI.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.bench.rmi; 8 | import java.rmi.*; 9 | import java.rmi.server.UnicastRemoteObject; 10 | import java.util.Hashtable; 11 | import kilim.Task; 12 | public class RMI { 13 | public static void main(String[] args) throws Exception { 14 | int ntimes = args.length == 0 ? 1000 : Integer.parseInt(args[0]); 15 | Server obj = new Server(); 16 | Ping stub = (Ping) UnicastRemoteObject.exportObject(obj, 0); 17 | Hashtable h = new Hashtable(); 18 | h.put("foo", "bar"); 19 | h.put("hello", "world"); 20 | long begin = System.currentTimeMillis(); 21 | for (int i = 0; i < ntimes; i++) { 22 | // System.out.println("Sending hash " + System.identityHashCode(h)); 23 | stub.ping(i); 24 | } 25 | System.out.println("Elapsed (" + ntimes + " iters) : " + 26 | (System.currentTimeMillis() - begin) + " millis"); 27 | UnicastRemoteObject.unexportObject(obj,false); 28 | } 29 | } 30 | 31 | interface Ping extends Remote { 32 | // void ping(Hashtable h) throws RemoteException; 33 | void ping(int i) throws RemoteException; 34 | } 35 | 36 | class Server implements Ping { 37 | public void ping(int i) throws RemoteException { 38 | // System.out.println(i); 39 | } 40 | 41 | } 42 | 43 | -------------------------------------------------------------------------------- /bench/scala/BigPingPong.scala: -------------------------------------------------------------------------------- 1 | package examples.actors 2 | 3 | /* 4 | Adapted from PingPongEx.scala, itself an adaption of an example 5 | from the scala distribution (added timing measurement). 6 | 7 | This example creates n tasks and has each send a message to the 8 | others. It sends the same structure (and number of messages) as the 9 | kilim/bench/BigPingPong example. 10 | */ 11 | import scala.actors._ 12 | import scala.actors.Actor._ 13 | 14 | object BigPingPong { 15 | var beginTime: long = 0 16 | 17 | def main(args : Array[String]): Unit = { 18 | val nTasks = Integer.parseInt(args(0)) 19 | var i = nTasks 20 | var tasks: Array[Ping] = new Array[Ping](nTasks) 21 | // Scheduler.impl = new SingleThreadedScheduler 22 | val cTask = new Collector(nTasks); 23 | cTask.start() 24 | 25 | beginTime = System.currentTimeMillis() 26 | for (val i <- 0 to nTasks-1) { 27 | tasks(i) = new Ping(i) 28 | } 29 | for (val t <- tasks) { 30 | t.setOthers(tasks, cTask) 31 | t.start() 32 | } 33 | val p = Start() 34 | for (val t <- tasks) { 35 | t ! p 36 | } 37 | } 38 | } 39 | 40 | abstract class Msg 41 | case class PingMsg(from :int ) extends Msg 42 | case class Start() extends Msg 43 | 44 | class Ping(i: int) extends Actor { 45 | var id : int = i 46 | var tasks: Array[Ping] = Array() 47 | var ctask : Collector = null 48 | 49 | def setOthers(others: Array[Ping], ct : Collector) { 50 | ctask = ct 51 | tasks = others 52 | } 53 | 54 | def act(): unit = { 55 | var pingsExpected : int = tasks.length - 1 56 | val p = PingMsg(id) 57 | loop { 58 | react { 59 | case Start() => { 60 | for (val t <- tasks) { 61 | if (t != this) { 62 | t ! p 63 | // System.out.println("Sending: " + id + "->" + t.id); 64 | } 65 | } 66 | // System.out.println("Done sending " + id); 67 | } 68 | case PingMsg(from) => { 69 | pingsExpected = pingsExpected - 1; 70 | // System.out.println("Rcvd: " + from + "->" + id + " " + pingsExpected); 71 | if (pingsExpected == 0) { 72 | ctask ! p 73 | } 74 | } 75 | } 76 | } 77 | } 78 | } 79 | 80 | 81 | class Collector(n : int) extends Actor { 82 | val nTasks = n 83 | 84 | def act(): unit = { 85 | for (val i <- 1 to nTasks) { 86 | receive { 87 | case PingMsg(from) => { 88 | //System.out.println("Completed: " + from); 89 | } 90 | } 91 | } 92 | 93 | val elapsed = System.currentTimeMillis() - BigPingPong.beginTime; 94 | System.out.println("Elapsed : " + elapsed) 95 | System.exit(0); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /bench/scala/Msg.scala: -------------------------------------------------------------------------------- 1 | package examples.actors 2 | 3 | abstract class PingMessage 4 | case class MsgStart() extends PingMessage 5 | case class MsgPingInit(count: int, pong: Pong) extends PingMessage 6 | case class MsgSendPing extends PingMessage 7 | case class MsgPong(sender: Pong) extends PingMessage 8 | 9 | abstract class PongMessage 10 | case class MsgPing(sender: Ping) extends PongMessage 11 | case class MsgStop() extends PongMessage 12 | 13 | -------------------------------------------------------------------------------- /bench/scala/PingPongEx.scala: -------------------------------------------------------------------------------- 1 | package examples.actors 2 | 3 | import scala.actors.Actor 4 | import scala.actors.Actor._ 5 | 6 | abstract class PingMessage 7 | case class MsgStart() extends PingMessage 8 | case class MsgPingInit(count: int, pong: Pong) extends PingMessage 9 | case class MsgSendPing extends PingMessage 10 | case class MsgPong(sender: Pong) extends PingMessage 11 | 12 | abstract class PongMessage 13 | case class MsgPing(sender: Ping) extends PongMessage 14 | case class MsgStop() extends PongMessage 15 | 16 | object PingPongBench { 17 | def main(args : Array[String]): Unit = { 18 | val ping = new Ping 19 | ping.start 20 | val pong = new Pong 21 | pong.start 22 | ping ! MsgPingInit(100000, pong) 23 | ping ! MsgStart 24 | } 25 | } 26 | 27 | 28 | class Ping extends Actor { 29 | var beginTime: long = 0; 30 | def act(): unit = { 31 | loop(0, null) 32 | } 33 | def loop(pingsLeft: int, pong: Pong): unit = { 34 | react { 35 | case MsgPingInit(count, pong) => { 36 | // System.out.println("Ping: Initializing with count:"+count+":"+pong) 37 | beginTime = System.currentTimeMillis(); 38 | loop(count, pong) 39 | } 40 | case MsgStart() => { 41 | // System.out.println("Ping: starting.") 42 | pong ! MsgPing(this) 43 | loop(pingsLeft-1, pong) 44 | } 45 | case MsgSendPing() => { 46 | pong ! MsgPing(this) 47 | loop(pingsLeft-1, pong) 48 | } 49 | case MsgPong(pidS) => { 50 | // if (pingsLeft % 100 == 0) { 51 | // System.out.println("Ping: pong from: "+pidS) 52 | // } 53 | if (pingsLeft > 0) 54 | this ! MsgSendPing() 55 | else { 56 | // System.out.println("Ping: Stop.") 57 | System.out.println("Elapsed: " + (System.currentTimeMillis() - beginTime)); 58 | pong ! MsgStop() 59 | } 60 | loop(pingsLeft, pong) 61 | } 62 | } 63 | } 64 | } 65 | 66 | class Pong extends Actor { 67 | def act(): unit = { 68 | loop(0) 69 | } 70 | 71 | def loop(pongCount: int): unit = { 72 | react { 73 | case MsgPing(pidPing) => { 74 | // if (pongCount % 100 == 0) { 75 | // System.out.println("Pong: ping:"+pongCount+" from: "+pidPing) 76 | // } 77 | pidPing ! MsgPong(this) 78 | loop(pongCount+1) 79 | } 80 | case MsgStop() => { 81 | // System.out.println("Pong: Stop.") 82 | System.exit(0) 83 | } 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /bench/scala/oBigPingPong.scala: -------------------------------------------------------------------------------- 1 | package examples.actors 2 | 3 | /* 4 | Adapted from PingPongEx.scala, itself an adaption of an example 5 | from the scala distribution (added timing measurement). 6 | 7 | This example creates n tasks and has each send a message to the 8 | others. It sends the same structure (and number of messages) as the 9 | kilim/bench/BigPingPong example. 10 | */ 11 | import scala.actors._ 12 | import scala.actors.Actor._ 13 | 14 | object BigPingPong { 15 | var beginTime: long = 0 16 | 17 | def main(args : Array[String]): Unit = { 18 | val nTasks = Integer.parseInt(args(0)) 19 | var i = nTasks 20 | var tasks: Array[Ping] = new Array[Ping](nTasks) 21 | Scheduler.impl = new SingleThreadedScheduler 22 | val cTask = new Collector(nTasks); 23 | cTask.start() 24 | 25 | beginTime = System.currentTimeMillis() 26 | for (val i <- 0 to nTasks-1) { 27 | tasks(i) = new Ping(i) 28 | } 29 | for (val t <- tasks) { 30 | t.setOthers(tasks, cTask) 31 | t.start(); 32 | } 33 | } 34 | } 35 | 36 | abstract class Msg 37 | case class PingMsg(from :int ) extends Msg 38 | 39 | class Ping(i: int) extends Actor { 40 | var id : int = i 41 | var tasks: Array[Ping] = Array() 42 | var ctask : Collector = null 43 | 44 | def setOthers(others: Array[Ping], ct : Collector) { 45 | ctask = ct 46 | tasks = others 47 | } 48 | 49 | def act(): unit = { 50 | System.out.println("" + id + " n = " + tasks.length); 51 | for (val t <- tasks) { 52 | if (t != this) { 53 | t ! new PingMsg(id) 54 | receive { 55 | case PingMsg(from) => { 56 | System.out.println ("" + from + " -> " + id); 57 | } 58 | } 59 | } 60 | } 61 | ctask ! new PingMsg(id) 62 | } 63 | } 64 | 65 | 66 | class Collector(n : int) extends Actor { 67 | val nTasks = n 68 | 69 | def act(): unit = { 70 | for (val i <- 1 to nTasks) { 71 | receive { 72 | case PingMsg(from) => { 73 | //System.out.println("Completed: " + from); 74 | } 75 | } 76 | } 77 | 78 | val elapsed = System.currentTimeMillis() - BigPingPong.beginTime; 79 | System.out.println("Elapsed : " + elapsed) 80 | System.exit(0); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /demos/.gitignore: -------------------------------------------------------------------------------- 1 | /*/target/ 2 | -------------------------------------------------------------------------------- /demos/battle/pom.xml: -------------------------------------------------------------------------------- 1 | ../poms/pom.xml -------------------------------------------------------------------------------- /demos/battle/pom11.xml: -------------------------------------------------------------------------------- 1 | ../poms/pom11.xml -------------------------------------------------------------------------------- /demos/battle/pom12.xml: -------------------------------------------------------------------------------- 1 | ../poms/pom12.xml -------------------------------------------------------------------------------- /demos/battle/pom13.xml: -------------------------------------------------------------------------------- 1 | ../poms/pom13.xml -------------------------------------------------------------------------------- /demos/battle/pom9.xml: -------------------------------------------------------------------------------- 1 | ../poms/pom9.xml -------------------------------------------------------------------------------- /demos/battle/src/main/java/kilim/demo/Battle.java: -------------------------------------------------------------------------------- 1 | package kilim.demo; 2 | 3 | import java.util.Random; 4 | import java.util.concurrent.atomic.AtomicInteger; 5 | import kilim.Mailbox; 6 | import kilim.Pausable; 7 | import kilim.Task; 8 | 9 | public class Battle { 10 | static Random rand = new Random(); 11 | int num = 1000; 12 | Actor [] actors = new Actor[num]; 13 | AtomicInteger living = new AtomicInteger(num); 14 | 15 | 16 | public class Actor extends Task { 17 | Mailbox damage = new Mailbox<>(); 18 | int hp = 1 + rand.nextInt(10); 19 | 20 | public void execute() throws Pausable { 21 | while (hp > 0) { 22 | hp -= damage.get(); 23 | actors[rand.nextInt(num)].damage.putnb(1); 24 | actors[rand.nextInt(num)].damage.putnb(1); 25 | actors[rand.nextInt(num)].damage.putnb(1); 26 | Task.sleep(100); 27 | } 28 | living.decrementAndGet(); 29 | } 30 | } 31 | 32 | void start() { 33 | for (int ii=0; ii < num; ii++) (actors[ii] = new Actor()).start(); 34 | actors[0].damage.putb(1); 35 | 36 | for (int cnt, prev=num; (cnt=living.get()) > num/2 || cnt < prev; prev=cnt, sleep()) 37 | System.out.println(cnt); 38 | 39 | } 40 | 41 | static void sleep() { 42 | try { Thread.sleep(100); } 43 | catch (InterruptedException ex) {} 44 | } 45 | 46 | public static void main(String [] args) { 47 | if (kilim.tools.Kilim.trampoline(false,args)) return; 48 | Battle battle = new Battle(); 49 | battle.start(); 50 | Task.idledown(); 51 | System.out.format("\n%d actors survived the Battle Royale\n\n",battle.living.get()); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /demos/battle10/pom-weave.xml: -------------------------------------------------------------------------------- 1 | ../poms/pom10-weave.xml -------------------------------------------------------------------------------- /demos/battle10/pom.xml: -------------------------------------------------------------------------------- 1 | ../poms/pom10.xml -------------------------------------------------------------------------------- /demos/battle10/src/main/java/kilim/demo/Battle.java: -------------------------------------------------------------------------------- 1 | package kilim.demo; 2 | 3 | import java.util.Random; 4 | import java.util.concurrent.atomic.AtomicInteger; 5 | import kilim.Mailbox; 6 | import kilim.Pausable; 7 | import kilim.Task; 8 | 9 | /* 10 | kilim battle demo 10 11 | the battle demo using java 10 features (var) 12 | */ 13 | 14 | public class Battle { 15 | static Random rand = new Random(); 16 | int num = 1000; 17 | Actor [] actors = new Actor[num]; 18 | AtomicInteger living = new AtomicInteger(num); 19 | 20 | 21 | public class Actor extends Task { 22 | Mailbox damage = new Mailbox<>(); 23 | int hp = 1 + rand.nextInt(10); 24 | 25 | public void strike() throws Pausable { 26 | // token use of java-10-feature var 27 | var victim = rand.nextInt(num); 28 | var mb = actors[victim].damage; 29 | mb.putnb(1); 30 | } 31 | 32 | public void execute() throws Pausable { 33 | while (hp > 0) { 34 | hp -= damage.get(); 35 | strike(); 36 | strike(); 37 | strike(); 38 | Task.sleep(100); 39 | } 40 | living.decrementAndGet(); 41 | } 42 | } 43 | 44 | void start() { 45 | for (int ii=0; ii < num; ii++) (actors[ii] = new Actor()).start(); 46 | actors[0].damage.putb(1); 47 | 48 | for (int cnt, prev=num; (cnt=living.get()) > num/2 || cnt < prev; prev=cnt, sleep()) 49 | System.out.println(cnt); 50 | 51 | } 52 | 53 | static void sleep() { 54 | try { Thread.sleep(100); } 55 | catch (InterruptedException ex) {} 56 | } 57 | 58 | // force kilim to weave the class so we're able to detect runtime weaving 59 | private void unused() throws Pausable {} 60 | 61 | public static void main(String [] args) { 62 | System.out.println("pre weave announcement (appears twice for runtime weaving)"); 63 | if (kilim.tools.Kilim.trampoline(true,args)) return; 64 | Battle battle = new Battle(); 65 | battle.start(); 66 | Task.idledown(); 67 | System.out.format("\n%d actors survived the Battle Royale\n\n",battle.living.get()); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /demos/battle10/src/main/java/kilim/demo/HelloWorld.java: -------------------------------------------------------------------------------- 1 | // copyright 2018 nqzero - offered under the terms of the MIT License 2 | 3 | package kilim.demo; 4 | 5 | import kilim.Mailbox; 6 | import kilim.Task; 7 | 8 | public class HelloWorld { 9 | 10 | public static void main(String[] args) throws Exception { 11 | System.out.println("pre weave announcement (appears twice for runtime weaving)"); 12 | if (kilim.tools.Kilim.trampoline(true,args)) return; 13 | Mailbox mb = new Mailbox(100,1000); 14 | 15 | int num = 100, delay = 1000, val = -1; 16 | if (args.length > 0) num = Integer.parseInt(args[0]); 17 | long t0 = 0, t1=0; 18 | 19 | for (int jj = 0; jj < 10; jj++, t0=t1) { 20 | for (int ii=0; ii < num; ii++) 21 | Task.fork(fiber -> { 22 | Task.sleep(delay); 23 | mb.put(1); 24 | }); 25 | for (int ii=0; ii < num; ii++) { 26 | int tmp = mb.getb(); 27 | if (tmp != 1) 28 | System.out.println("tmp: " + tmp); 29 | val += tmp; 30 | } 31 | t1 = System.currentTimeMillis(); 32 | System.out.format("hello world: %d in %d millis\n",val,t1-t0); 33 | } 34 | 35 | Task.idledown(); 36 | } 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /demos/invoke/pom.xml: -------------------------------------------------------------------------------- 1 | ../poms/pom.xml -------------------------------------------------------------------------------- /demos/invoke/src/main/java/kilim/demo/CodeA.java: -------------------------------------------------------------------------------- 1 | package kilim.demo; 2 | 3 | import kilim.*; 4 | 5 | public class CodeA implements CodeB { 6 | public void doSome() throws Pausable, Exception { 7 | Task.sleep(1500); 8 | System.out.println("\n\nPausable runtime-woven method successfully invoked\n\n"); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /demos/invoke/src/main/java/kilim/demo/CodeB.java: -------------------------------------------------------------------------------- 1 | package kilim.demo; 2 | 3 | import kilim.Pausable; 4 | 5 | public interface CodeB { 6 | void doSome() throws Exception, Pausable; 7 | } 8 | 9 | -------------------------------------------------------------------------------- /demos/java11/README.md: -------------------------------------------------------------------------------- 1 | # demo of JEP 330 single-file source invocation 2 | 3 | kilim is able to run some source files. 4 | JEP 330 class loading doesn't support all features, so source may need to be modified somewhat 5 | 6 | 7 | ## invocation 8 | 9 | java 12: 10 | ``` 11 | cp=$(mvn -q dependency:build-classpath -Dmdep.outputFile=/dev/fd/1) 12 | $java12/bin/java -cp $cp ../../src/kilim/examples/Xorshift.java 13 | ``` 14 | 15 | for java 11, need an agent to access the bytecode: 16 | ``` 17 | cp=$(mvn -q dependency:build-classpath -Dmdep.outputFile=/dev/fd/1) 18 | kilim="-javaagent:${cp/:*} -cp $cp" 19 | $java11/bin/java $kilim ../../src/kilim/examples/Xorshift.java 20 | ``` 21 | 22 | ## caveats 23 | 24 | - need to enable runtime weaving 25 | - call `Kilim.trampoline` in main with a classloader template, eg: 26 | - `new Object() {}` 27 | - or `Xorshift.class` 28 | - see `kilim.examples.Xorshift`, esp the first lines of `main` 29 | - the bytecode was made available in java 12 via https://bugs.openjdk.java.net/browse/JDK-8210009 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /demos/java11/pom.xml: -------------------------------------------------------------------------------- 1 | ../poms/pom11.xml -------------------------------------------------------------------------------- /demos/java11/src/main/java/kilim/demo/LambdaToFile.java: -------------------------------------------------------------------------------- 1 | package kilim.demo; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FileOutputStream; 6 | import java.io.IOException; 7 | import java.io.ObjectInputStream; 8 | import java.io.ObjectOutputStream; 9 | import java.io.Serializable; 10 | import kilim.Pausable; 11 | import kilim.Task; 12 | import kilim.tools.Kilim; 13 | 14 | /** 15 | * demo of saving and loading a pausable lambda using a file. 16 | * if the file is present, it's not regenerated. 17 | * if the file is loaded, it's deleted on exit 18 | */ 19 | public class LambdaToFile { 20 | public interface SerFork extends Serializable, Pausable.Fork {} 21 | 22 | public static void main(String[] args) throws Exception { 23 | if (Kilim.trampoline(false,args)) return; 24 | String name = "file.jobj"; 25 | File file = new File(name); 26 | if (file.exists()) 27 | file.deleteOnExit(); 28 | else { 29 | SerFork body = () -> { 30 | Task.sleep(1000); 31 | System.out.println("fork has slept: " + args + name); 32 | }; 33 | System.out.println("saving file: " + name); 34 | save(body,name); 35 | } 36 | SerFork body = (SerFork) load(name); 37 | Task.fork(body).joinb(); 38 | } 39 | public static void save(Object obj,String name) throws Exception { 40 | FileOutputStream fos = new FileOutputStream(name); 41 | ObjectOutputStream out = new ObjectOutputStream(fos); 42 | out.writeObject(obj); 43 | out.close(); 44 | fos.close(); 45 | } 46 | public static Object load(String name) throws Exception { 47 | FileInputStream fin = new FileInputStream(name); 48 | ObjectInputStream in = new ObjectInputStream(fin); 49 | Object obj = in.readObject(); 50 | in.close(); 51 | fin.close(); 52 | return obj; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /demos/java7/pom.xml: -------------------------------------------------------------------------------- 1 | ../poms/pom7.xml -------------------------------------------------------------------------------- /demos/java7/readme.txt: -------------------------------------------------------------------------------- 1 | # an example of using java 7 2 | # java 8 is the standard environment for kilim, but java 7 should still work 3 | # note: java 6 should work too but this is untested - i don't have a dev environment for it 4 | # some features depend on java 8, including the jetty support 5 | # using maven plugins with a classifier doesn't work, so jdk-specific version numbers are used 6 | 7 | 8 | # build and run the demo 9 | JAVA_HOME=$java7 mvn -Dhttps.protocols=TLSv1.2 clean package exec:java -Dexec.mainClass=kilim.demo.Battle 10 | 11 | 12 | # not all versions are available in maven central compiled for java 7, so you may need to install locally 13 | # in the toplevel kilim directory, build and install with java 7 14 | 15 | version=2.0.1-jdk7 16 | mvn versions:set -DnewVersion=$version 17 | JAVA_HOME=$java7 ant clean weave jar 18 | mvn install:install-file -DpomFile=pom.xml -Dfile=target/kilim.jar 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /demos/java7/src/main/java/kilim/demo/Battle.java: -------------------------------------------------------------------------------- 1 | package kilim.demo; 2 | 3 | import java.util.Random; 4 | import java.util.concurrent.atomic.AtomicInteger; 5 | import kilim.Mailbox; 6 | import kilim.Pausable; 7 | import kilim.Task; 8 | 9 | public class Battle { 10 | static Random rand = new Random(); 11 | int num = 1000; 12 | Actor [] actors = new Actor[num]; 13 | AtomicInteger living = new AtomicInteger(num); 14 | 15 | 16 | public class Actor extends Task { 17 | Mailbox damage = new Mailbox<>(); 18 | int hp = 1 + rand.nextInt(10); 19 | 20 | public void execute() throws Pausable { 21 | while (hp > 0) { 22 | hp -= damage.get(); 23 | actors[rand.nextInt(num)].damage.putnb(1); 24 | actors[rand.nextInt(num)].damage.putnb(1); 25 | actors[rand.nextInt(num)].damage.putnb(1); 26 | Task.sleep(100); 27 | } 28 | living.decrementAndGet(); 29 | } 30 | } 31 | 32 | void start() { 33 | for (int ii=0; ii < num; ii++) (actors[ii] = new Actor()).start(); 34 | actors[0].damage.putb(1); 35 | 36 | for (int cnt, prev=num; (cnt=living.get()) > num/2 || cnt < prev; prev=cnt, sleep()) 37 | System.out.println(cnt); 38 | 39 | } 40 | 41 | static void sleep() { 42 | try { Thread.sleep(100); } 43 | catch (InterruptedException ex) {} 44 | } 45 | 46 | public static void main(String [] args) { 47 | if (kilim.tools.Kilim.trampoline(false,args)) return; 48 | Battle battle = new Battle(); 49 | battle.start(); 50 | Task.idledown(); 51 | System.out.format("\n%d actors survived the Battle Royale\n\n",battle.living.get()); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /demos/jetty/pom.xml: -------------------------------------------------------------------------------- 1 | ../poms/pom-jetty.xml -------------------------------------------------------------------------------- /demos/jetty/src/main/java/kilim/demo/KilimHandler.java: -------------------------------------------------------------------------------- 1 | package kilim.demo; 2 | 3 | import org.eclipse.jetty.server.Server; 4 | 5 | 6 | 7 | public class KilimHandler { 8 | 9 | public static void main(String[] args) throws Exception { 10 | Server server = new Server(9104); 11 | server.setHandler(new kilim.support.JettyHandler((target,raw,req,resp) -> { 12 | return "cruel world"; 13 | })); 14 | server.start(); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /demos/jetty/src/main/java/kilim/demo/KilimServlet.java: -------------------------------------------------------------------------------- 1 | package kilim.demo; 2 | 3 | import java.io.IOException; 4 | import java.nio.ByteBuffer; 5 | import javax.servlet.AsyncContext; 6 | import javax.servlet.ServletException; 7 | import javax.servlet.http.HttpServlet; 8 | import javax.servlet.http.HttpServletRequest; 9 | import javax.servlet.http.HttpServletResponse; 10 | import kilim.Pausable; 11 | import kilim.Task; 12 | import org.eclipse.jetty.http.HttpField; 13 | import org.eclipse.jetty.http.HttpHeader; 14 | import org.eclipse.jetty.http.MimeTypes; 15 | import org.eclipse.jetty.http.PreEncodedHttpField; 16 | import org.eclipse.jetty.server.Request; 17 | import org.eclipse.jetty.server.Server; 18 | import org.eclipse.jetty.servlet.ServletContextHandler; 19 | import org.eclipse.jetty.servlet.ServletHolder; 20 | import org.eclipse.jetty.util.BufferUtil; 21 | 22 | 23 | 24 | public class KilimServlet extends HttpServlet { 25 | ByteBuffer helloWorld = BufferUtil.toBuffer("hello world"); 26 | HttpField contentType = new PreEncodedHttpField(HttpHeader.CONTENT_TYPE,MimeTypes.Type.TEXT_PLAIN.asString()); 27 | private static int delay = 1000; 28 | 29 | void reply(AsyncContext async) { 30 | try { 31 | Request br = (Request) async.getRequest(); 32 | br.setHandled(true); 33 | br.getResponse().getHttpFields().add(contentType); 34 | br.getResponse().getHttpOutput().sendContent(helloWorld.slice()); 35 | async.complete(); 36 | } catch (IOException ex) {} 37 | } 38 | 39 | protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 40 | final AsyncContext async = req.startAsync(); 41 | async.setTimeout(30000); 42 | new kilim.Task() { 43 | public void execute() throws Pausable, Exception { 44 | if (delay > 0) Task.sleep(delay); 45 | reply(async); 46 | } 47 | }.start(); 48 | } 49 | 50 | 51 | 52 | public static void main(String[] args) throws Exception { 53 | if (args.length > 0) delay = Integer.valueOf(args[0]); 54 | Server server = new Server(9099); 55 | ServletContextHandler context = new ServletContextHandler(); 56 | context.setContextPath("/"); 57 | ServletHolder holder = new ServletHolder(new KilimServlet()); 58 | holder.setAsyncSupported(true); 59 | context.addServlet(holder,"/hello"); 60 | server.setHandler(context); 61 | server.start(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /demos/jetty7/pom.xml: -------------------------------------------------------------------------------- 1 | ../poms/pom7-jetty.xml -------------------------------------------------------------------------------- /demos/jetty7/src/main/java/kilim/demo/KilimHandler7.java: -------------------------------------------------------------------------------- 1 | package kilim.demo; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.servlet.http.HttpServletResponse; 5 | import kilim.Pausable; 6 | import kilim.Task; 7 | import kilim.support.JettyHandler; 8 | import org.eclipse.jetty.server.Request; 9 | import org.eclipse.jetty.server.Server; 10 | 11 | 12 | /* 13 | kilim uses provided-scope for it's jetty support using jetty 9.3, which is java 8+ only 14 | this example project shows that kilim can be used with an older jetty with java 7 15 | */ 16 | 17 | 18 | /** example of using kilim's JettyHandler and jetty on java 7 - it works, though less elegant without lambdas */ 19 | public class KilimHandler7 { 20 | 21 | public static void main(String[] args) throws Exception { 22 | Server server = new Server(9104); 23 | MyHandler7 handler = new MyHandler7(); 24 | server.setHandler(new JettyHandler(handler)); 25 | server.start(); 26 | } 27 | 28 | public static class MyHandler7 extends JettyHandler.Java7Handler { 29 | public String handle(String target,Request br,HttpServletRequest req,HttpServletResponse resp) throws Pausable,Exception { 30 | Task.sleep(1000); 31 | return "cruel world = " + req.getPathInfo(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /demos/jshell/README.md: -------------------------------------------------------------------------------- 1 | demo of using kilim and runtime weaving with jshell, ie defining pausable methods inside jshell 2 | 3 | 4 | here's a transcript: 5 | 6 | 7 | ``` 8 | mvn compile 9 | cp=$(mvn -q dependency:build-classpath -Dmdep.outputFile=/dev/fd/1) 10 | $java9/bin/java -cp target/classes:$cp Kshell 11 | 12 | 13 | 14 | jshell> import kilim.*; 15 | 16 | jshell> Mailbox mb = new Mailbox<>(); 17 | mb ==> id:729803618 numMsgs:0 18 | 19 | jshell> Task.fork(() -> { for (int ii=0; ii < 5; ii++) { Task.sleep(1000); mb.put(ii); } }) 20 | $39 ==> 24(running=true,pr=null) 21 | 22 | jshell> for (Integer val=0; val != null;) System.out.println(val = mb.getb(2000)); 23 | 0 24 | 1 25 | 2 26 | 3 27 | 4 28 | null 29 | 30 | jshell> /exit 31 | | Goodbye 32 | ``` 33 | 34 | 35 | notes: 36 | 37 | * jshell (not kilim) creates a timer thread that doesn't exit cleanly, and maven would wait for it. 38 | so i call `System.exit` instead 39 | 40 | * the toplevel jshell method is not pausable (similar to `main()`) so it's not possible to call pausable methods directly 41 | 42 | * use `Task.fork` or `Task.spawn` or `new Task() {}.start()` to start a task 43 | 44 | * use blocking methods to access mailboxes and tasks, eg `mb.getb(2000)` or `task.joinb()` 45 | 46 | * calling pausable methods directly causes a `KilimException` and causes jshell to terminate. since this can be inconvenient, it may be handled more gracefully in the future 47 | 48 | * there's a java 10 bug that openjdk fixed in java 11 (but won't backport to 10) that affects some kilim lambdas. use a `-jdk10` versioned artifact in the meantime if you experience errors such as `java.lang.NoClassDefFoundError thrown: REPL/$JShell$17$$Lambda$437` 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /demos/jshell/pom.xml: -------------------------------------------------------------------------------- 1 | ../poms/pom11.xml -------------------------------------------------------------------------------- /demos/jshell/src/main/resources/META-INF/services/jdk.jshell.spi.ExecutionControlProvider: -------------------------------------------------------------------------------- 1 | Kshell$Prov 2 | -------------------------------------------------------------------------------- /demos/poms/pom-jetty.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | org.db4j 5 | kilim-demo-jetty 6 | 0.1 7 | 8 | 9 | 10 | org.db4j 11 | kilim 12 | 2.0.2 13 | 14 | 15 | org.eclipse.jetty 16 | jetty-server 17 | ${jetty.version} 18 | 19 | 20 | org.eclipse.jetty 21 | jetty-util-ajax 22 | ${jetty.version} 23 | 24 | 25 | org.eclipse.jetty 26 | jetty-webapp 27 | ${jetty.version} 28 | 29 | 30 | 31 | 32 | 1.8 33 | 1.8 34 | 9.3.0.v20150612 35 | none 36 | 37 | 38 | 39 | 40 | 41 | org.db4j 42 | kilim 43 | 2.0.2 44 | 45 | 46 | weave 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /demos/poms/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | org.db4j 5 | kilim-demo 6 | 0.1 7 | 8 | 9 | 10 | org.db4j 11 | kilim 12 | 2.0.2 13 | 14 | 15 | 16 | 17 | 1.8 18 | 1.8 19 | none 20 | 21 | 22 | -------------------------------------------------------------------------------- /demos/poms/pom10-weave.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | org.db4j 5 | kilim-demo-10 6 | 0.1 7 | 8 | 9 | 10 | org.db4j 11 | kilim 12 | 2.0.0-28-jdk10 13 | 14 | 15 | 16 | 17 | 10 18 | 10 19 | 10 20 | none 21 | 22 | 23 | 24 | 25 | 26 | org.db4j 27 | kilim 28 | 2.0.0-28-jdk10 29 | 30 | 31 | weave 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /demos/poms/pom10.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | org.db4j 5 | kilim-demo-10 6 | 0.1 7 | 8 | 9 | 10 | org.db4j 11 | kilim 12 | 2.0.0-28-jdk10 13 | 14 | 15 | 16 | 17 | 10 18 | 10 19 | 10 20 | none 21 | 22 | 23 | -------------------------------------------------------------------------------- /demos/poms/pom11.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | org.db4j 5 | kilim-demo-11 6 | 0.1 7 | 8 | 9 | 10 | org.db4j 11 | kilim 12 | 2.0.2 13 | 14 | 15 | 16 | 17 | 11 18 | 11 19 | 11 20 | none 21 | 22 | 23 | -------------------------------------------------------------------------------- /demos/poms/pom12.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | org.db4j 5 | kilim-demo-12 6 | 0.1 7 | 8 | 9 | 10 | org.db4j 11 | kilim 12 | 2.0.2 13 | 14 | 15 | 16 | 17 | 12 18 | 12 19 | 12 20 | none 21 | 22 | 23 | -------------------------------------------------------------------------------- /demos/poms/pom13.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | org.db4j 5 | kilim-demo-13 6 | 0.1 7 | 8 | 9 | 10 | org.db4j 11 | kilim 12 | 2.0.2 13 | 14 | 15 | 16 | 17 | 13 18 | 13 19 | 13 20 | none 21 | 22 | 23 | -------------------------------------------------------------------------------- /demos/poms/pom7-jetty.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | org.db4j 5 | kilim-demo-jetty7 6 | 0.1 7 | 8 | 9 | 10 | org.db4j 11 | kilim 12 | 2.0.2-jdk7 13 | 14 | 15 | org.eclipse.jetty 16 | jetty-server 17 | ${jetty.version} 18 | 19 | 20 | org.eclipse.jetty 21 | jetty-util-ajax 22 | ${jetty.version} 23 | 24 | 25 | org.eclipse.jetty 26 | jetty-webapp 27 | ${jetty.version} 28 | 29 | 30 | 31 | 32 | 1.7 33 | 1.7 34 | 9.2.24.v20180105 35 | none 36 | 37 | 38 | 39 | 40 | 41 | org.db4j 42 | kilim 43 | 2.0.2-jdk7 44 | 45 | 46 | weave 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /demos/poms/pom7.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | org.db4j 5 | kilim-demo-7 6 | 0.1 7 | 8 | 9 | 10 | org.db4j 11 | kilim 12 | 2.0.2-jdk7 13 | 14 | 15 | 16 | 17 | 1.7 18 | 1.7 19 | none 20 | 21 | 22 | -------------------------------------------------------------------------------- /demos/poms/pom9.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | org.db4j 5 | kilim-demo-9 6 | 0.1 7 | 8 | 9 | 10 | org.db4j 11 | kilim 12 | 2.0.2 13 | 14 | 15 | 16 | 17 | 1.9 18 | 1.9 19 | 9 20 | none 21 | 22 | 23 | -------------------------------------------------------------------------------- /docs/archive/build.sh: -------------------------------------------------------------------------------- 1 | export CLASSPATH=./classes:./testclasses:./libs/\*:$CLASSPATH 2 | 3 | echo making dir: ./classes 4 | rm -rf ./classes 5 | rm -rf ./testclasses 6 | mkdir ./classes 7 | mkdir ./testclasses 8 | 9 | echo Compiling java source =========================================== 10 | javac -Xlint:unchecked -XDignore.symbol.file -g -d ./classes `find . -name "*.java" ` 11 | 12 | echo Compiling .j files for testing ================================== 13 | java -ea kilim.tools.Asm -nf -d ./classes `find . -name "*.j"` 14 | 15 | echo Weaving ========================================================= 16 | # Weave all files under ./classes, compiling the tests to 17 | # ./testclasses while excluding any that match "ExInvalid". These are 18 | # negative tests for the Weaver. 19 | java -ea kilim.tools.Weaver -d ./classes -x "ExInvalid|test" ./classes 20 | java -ea kilim.tools.Weaver -d ./testclasses -x "ExInvalid" ./classes 21 | 22 | 23 | -------------------------------------------------------------------------------- /docs/archive/test.sh: -------------------------------------------------------------------------------- 1 | echo "Testing Kilim Weaver" 2 | java -ea -cp ./classes:./libs/asm-all-5.0.3.jar:./libs/junit.jar junit.textui.TestRunner kilim.test.AllNotWoven 3 | 4 | echo "Task, mailbox tests" 5 | java -ea -Dkilim.Scheduler.numThreads=10 -cp ./testclasses:./classes:./libs/asm-all-5.0.3.jar:./libs/junit.jar junit.textui.TestRunner kilim.test.AllWoven 6 | -------------------------------------------------------------------------------- /docs/demos.md: -------------------------------------------------------------------------------- 1 | battle 2 | pom11.xml pom9.xml pom.xml 3 | src/main/java/kilim/demo/Battle.java 4 | 5 | 6 | battle10 7 | pom-weave.xml pom.xml 8 | src/main/java/kilim/demo/HelloWorld.java 9 | src/main/java/kilim/demo/Battle.java 10 | 11 | 12 | invoke 13 | pom.xml 14 | src/main/java/kilim/demo/Invoke.java 15 | 16 | 17 | java11 18 | pom.xml 19 | 20 | 21 | java7 22 | pom.xml 23 | src/main/java/kilim/demo/Battle.java 24 | 25 | 26 | jetty 27 | pom.xml 28 | src/main/java/kilim/demo/KilimAsyncIO.java 29 | src/main/java/kilim/demo/KilimHandler.java 30 | src/main/java/kilim/demo/KilimServlet.java 31 | 32 | 33 | jetty7 34 | pom.xml 35 | src/main/java/kilim/demo/KilimHandler7.java 36 | 37 | 38 | -------------------------------------------------------------------------------- /docs/history.txt: -------------------------------------------------------------------------------- 1 | java 11 2 | the lack of JEP 330 classloader.getResources is being tracked 3 | https://bugs.openjdk.java.net/browse/JDK-8210009 4 | 5 | 6 | new features in 2.0 (by nqzero unless noted): 7 | - java 8, lambdas and Task.spawn (sriram) 8 | - runtime weaver 9 | - runtime trampoline 10 | - continuations (pure fibers) and fiber recycling 11 | offers dramatic speedup (20x) if scheduling is not required, eg for state machines 12 | - affine thread pool scheduler (concept by hedvig) 13 | - reduced synchronization in Task (hedvig) 14 | - high performance single producer and single consumer mailboxes (nilang) 15 | - no-context-switch timerservice (nilang) 16 | - ASM5 17 | - kilim web server: keepalive and expose query components 18 | - simplified class mirrors and detectors 19 | - hybrid build: maven for dependencies and ant for tests 20 | - maven plugin for weaving within a pom.xml 21 | - demo projects (battle royale, jetty) 22 | - idledown: automatically stop kilim when outstanding tasks complete 23 | - bytecode weaver bugfixes (nqzero, sriram) 24 | - maven packages for the cental repository 25 | 26 | 27 | 28 | taken as a whole, 2.0 represents a significant step forwards over 1.0 29 | 30 | __kilim maven plugin__ 31 | 32 | originally written by jestan 33 | integrated into kilim by nqzero 34 | license was apache 2.0, changed to MIT by jestan per this request: 35 | https://github.com/jestan/kilim-maven-plugin/issues/1 36 | 37 | 38 | 39 | __Older History__ 40 | 41 | sriram wrote the initial version in 2006 based on matthias mann's continuation library 42 | - many bugs were fixed 43 | - tracked changes to java language 44 | - feature set remained more or less unchanged thru 1.0 (circa 2013) 45 | 46 | -------------------------------------------------------------------------------- /docs/internals/fiber_states.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nqzero/kilim/16bc45e3a07ce074947722618982e90747dcb987/docs/internals/fiber_states.pdf -------------------------------------------------------------------------------- /docs/internals/task_states.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nqzero/kilim/16bc45e3a07ce074947722618982e90747dcb987/docs/internals/task_states.pdf -------------------------------------------------------------------------------- /docs/internals/task_states.txt: -------------------------------------------------------------------------------- 1 | See task_states.pdf 2 | 3 | Explanation of states: 4 | 5 | new: start not called 6 | 7 | ready: task.start()/resume() called. Task is in the 8 | scheduler q or has been taken out of it and handed to 9 | the thread. Note that task.running = true (doesn't reflect 10 | the 'running' state below) 11 | 12 | running: stack is resumed. task runs normally to completion 13 | or until Task.pause/yield/exit is called. 14 | 15 | pausing: pause called with a PauseReason object 16 | pauseReason can be user-defined. Predefined ones are 17 | YieldReason, TaskDoneReason, Empty_MsgAvListener, 18 | Full_SpcAvListener etc. 19 | 20 | Task.running remains true until it moves to paused state. 21 | 22 | paused: waiting for a message. 23 | Task.running = false /\ Task.pauseReason.isValid() 24 | 25 | done : task.execute() returned normally or with an unchecked exception 26 | or Task.exit() called 27 | 28 | ==================================================================== 29 | Messages and task scheduling 30 | 31 | What happens when a message arrives in each of the above states? 32 | 33 | new: no scheduling on msgs. start() explicitly schedules the task whether 34 | or not there are mailboxes. 35 | 36 | ready: 37 | running: 38 | no scheduling necessary when msg is put into mbox; task will rcv 39 | the message on get() The distinction between ready and running is 40 | not really important from a scheduling or message interaction 41 | perspective. 42 | 43 | pausing: no scheduling yet, because the task is still unwinding, 44 | But after the task is fully unwound, it'll be scheduled again if there 45 | are messages in an mbox that caused that task to pause in the first 46 | place. 47 | 48 | paused: Schedule the task. 49 | 50 | -------------------------------------------------------------------------------- /docs/kilim_ecoop08.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nqzero/kilim/16bc45e3a07ce074947722618982e90747dcb987/docs/kilim_ecoop08.pdf -------------------------------------------------------------------------------- /docs/limitations.md: -------------------------------------------------------------------------------- 1 | for the most part, kilim manages to weave arbitrary java code. 2 | this document attempts to enumerate the known limitations 3 | 4 | 5 | ### java 7 interface method annotations 6 | 7 | in java 7, annotations of interface methods are not preserved. 8 | https://github.com/kilim/kilim/issues/53 9 | 10 | this likely also affects class methods. 11 | the root cause is that the method is woven, the original is fiber-enabled 12 | and the original is replaced with a placeholder 13 | 14 | since java 7 is EOL, this may not be fixed. 15 | if you have a use case, add it to the bug report 16 | 17 | as a work-around, the annotation is applied to the fiber-enabled method, so check that method instead of the original 18 | 19 | ### constructors can not be pausable 20 | 21 | constructors must immediately call their super, so if a constructor yielded, 22 | the weaver would not be able to skip the super call on the subsequent execution 23 | 24 | we aren't aware of any means of working around this limitation, so it's highly 25 | unlikely that this limitation will be relaxed 26 | 27 | 28 | 29 | 30 | 31 | ### java 9 modules 32 | 33 | not currently supported but if you file an issue with a simple example that requires them 34 | the team is likely to add them 35 | 36 | -------------------------------------------------------------------------------- /docs/manual.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nqzero/kilim/16bc45e3a07ce074947722618982e90747dcb987/docs/manual.html -------------------------------------------------------------------------------- /docs/maven_plugin/README.md: -------------------------------------------------------------------------------- 1 | kilim-maven-plugin 2 | ================== 3 | 4 | the kilim maven artifact is also a maven plugin, ie it will weave your code ahead-of-time 5 | 6 | the default phase is process tests, which is needed to weave both classes and test classes. 7 | if you don't want to weave tests, or you're not running process tests, you'll need to override this, 8 | eg, with process classes 9 | 10 | 11 | How to use it 12 | ============= 13 | 14 | in your pom.xml 15 | 16 | ............ 17 | 18 | 19 | 20 | org.db4j 21 | kilim 22 | 2.0.1 23 | 24 | 25 | 26 | 27 | 28 | 29 | org.db4j 30 | kilim 31 | 2.0.1 32 | 33 | 34 | weave 35 | 36 | 37 | 38 | 39 | 40 | 41 | ............ 42 | 43 | 44 | afaik, the versions for the plugin must match the version for the dependency 45 | 46 | -------------------------------------------------------------------------------- /docs/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | line-height: 150%; 3 | /* font-size: 12pt;*/ 4 | border-style:none; 5 | font-family: verdana, helvetica; 6 | /* margin: 1em; */ 7 | } 8 | 9 | /* Links */ 10 | a:link {color: red; text-decoration:none} /* unvisited link */ 11 | a:visited {color: red; text-decoration:none} /* visited link */ 12 | a:hover {color: blue; background: yellow; text-decoration:none} /* mouse over link */ 13 | a:active {color: grey} /* selected link */ 14 | 15 | p,pre { 16 | line-height: 1.5em 17 | } 18 | 19 | h1 { 20 | background-color: #223322; 21 | Color: white; 22 | padding: 5px; 23 | padding-left: 20px; 24 | margin-left: -20px; 25 | margin-right: -20px; 26 | /* font-size: 15pt;*/ 27 | } 28 | 29 | 30 | pre {font-family: Monaco, Courier New, Courier; font-size:80%} 31 | code {font-family: Monaco, Courier New, Courier; font-size:80%} 32 | 33 | p code {margin: 5px} 34 | -------------------------------------------------------------------------------- /docs/thread_of_ones_own.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nqzero/kilim/16bc45e3a07ce074947722618982e90747dcb987/docs/thread_of_ones_own.pdf -------------------------------------------------------------------------------- /src/kilim/Constants.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | package kilim; 7 | 8 | import org.objectweb.asm.Opcodes; 9 | 10 | public interface Constants extends Opcodes { 11 | 12 | String KILIM_VERSION = "1.0"; 13 | int KILIM_ASM = ASM7; 14 | 15 | // Type descriptors 16 | String D_BOOLEAN = "Z"; 17 | String D_BYTE = "B"; 18 | String D_CHAR = "C"; 19 | String D_DOUBLE = "D"; 20 | String D_FLOAT = "F"; 21 | String D_INT = "I"; 22 | String D_LONG = "J"; 23 | String D_SHORT = "S"; 24 | String D_VOID = "V"; 25 | 26 | String D_ARRAY_BOOLEAN = "[Z"; 27 | String D_ARRAY_BYTE = "[B"; 28 | String D_ARRAY_CHAR = "[C"; 29 | String D_ARRAY_DOUBLE = "[D"; 30 | String D_ARRAY_FLOAT = "[F"; 31 | String D_ARRAY_SHORT = "[S"; 32 | String D_ARRAY_INT = "[I"; 33 | String D_ARRAY_LONG = "[J"; 34 | 35 | String D_NULL = "NULL"; 36 | String D_RETURN_ADDRESS = "A"; 37 | String D_OBJECT = "Ljava/lang/Object;"; 38 | String D_STRING = "Ljava/lang/String;"; 39 | String D_THROWABLE = "Ljava/lang/Throwable;"; 40 | String D_UNDEFINED = "UNDEFINED"; 41 | 42 | String D_FIBER = "Lkilim/Fiber;"; 43 | String D_STATE = "Lkilim/State;"; 44 | String D_TASK = "Lkilim/Task;"; 45 | String D_PAUSABLE = "Lkilim/Pausable;"; 46 | String D_FIBER_LAST_ARG = D_FIBER + ')'; // Last argument in a method descriptor 47 | 48 | String THROWABLE_CLASS = "java/lang/Throwable"; 49 | String FIBER_CLASS = "kilim/Fiber"; 50 | String STATE_CLASS = "kilim/State"; 51 | String TASK_CLASS = "kilim/Task"; 52 | String PAUSABLE_CLASS = "kilim/Pausable"; 53 | String NOT_PAUSABLE_CLASS = "kilim/NotPausable"; 54 | 55 | String WOVEN_FIELD = "$isWoven"; 56 | 57 | // Constant opcodes missing from asm's opcodes (as of asm 3.0) 58 | int ILOAD_0 = 26; 59 | int LLOAD_0 = 30; 60 | int FLOAD_0 = 34; 61 | int DLOAD_0 = 38; 62 | int ALOAD_0 = 42; 63 | int ISTORE_0 = 59; 64 | int LSTORE_0 = 63; 65 | int FSTORE_0 = 67; 66 | int DSTORE_0 = 71; 67 | int ASTORE_0 = 75; 68 | int LDC2_W = 20; 69 | 70 | String SAM_SHIM_PREFIX = "$shim$"; 71 | 72 | public static class Util { 73 | public static boolean isSamShim(String name) { 74 | return name.startsWith(SAM_SHIM_PREFIX); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/kilim/Event.java: -------------------------------------------------------------------------------- 1 | // Copyright 2006 by sriram - offered under the terms of the MIT License 2 | 3 | package kilim; 4 | 5 | public class Event { 6 | /** 7 | * Type of event to switch on. The first 1-1000 are reserved for kilim 8 | * If you define your own eventType, make sure there are no collisions 9 | * with other projects. One strategy to reduce collisions is to take 10 | * the ascii codes of the first four consonants of your project's name 11 | * 12 | */ 13 | public final int eventType; 14 | public Event(int evType) { 15 | eventType = evType; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/kilim/EventPublisher.java: -------------------------------------------------------------------------------- 1 | // Copyright 2009 by sriram - offered under the terms of the MIT License 2 | 3 | package kilim; 4 | 5 | public interface EventPublisher { 6 | } 7 | -------------------------------------------------------------------------------- /src/kilim/EventSubscriber.java: -------------------------------------------------------------------------------- 1 | // Copyright 2006 by sriram - offered under the terms of the MIT License 2 | 3 | package kilim; 4 | 5 | public interface EventSubscriber { 6 | void onEvent(EventPublisher ep, Event e); 7 | } 8 | -------------------------------------------------------------------------------- /src/kilim/ExitMsg.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim; 8 | 9 | /** 10 | * @see kilim.Task#informOnExit(Mailbox) 11 | */ 12 | public class ExitMsg { 13 | public final Task task; // exiting task 14 | public final TT result; // contains Throwable if exitCode == 1 15 | 16 | public ExitMsg(Task t,TT res) { 17 | task = t; 18 | result = res; 19 | } 20 | 21 | public String toString() { 22 | return "exit(" + task.id + "), result = " + result; 23 | } 24 | 25 | @Override 26 | public int hashCode() { 27 | return task.id; 28 | } 29 | @Override 30 | public boolean equals(Object obj) { 31 | return this == obj; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/kilim/Generator.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim; 8 | 9 | import java.util.Iterator; 10 | import java.util.NoSuchElementException; 11 | 12 | /** 13 | * A Generator, from the caller's perspective, looks like a normal iterator 14 | * that produces values. Because a standard iterator's next() method 15 | * must return every time, the programmer is forced to manage the stack 16 | * explicitly. The Generator class instead allows one to write a 17 | * task with an automatically managed stack and couple it to an 18 | * iterator interface. 19 | * 20 | * For example: 21 | * 22 | *
23 |  * class StringGenerator extends Generator{
24 |  *   public void execute() throws Pausable {
25 |  *       while (!done) {
26 |  *           String s = getNextWord(); // this can pause
27 |  *           yield(s);  
28 |  *       }
29 |  *   }
30 |  *   private String getNextWord() throws Pausable {
31 |  *   }
32 |  * }
33 |  * 
34 |  * 
35 |  * 
36 | * @see kilim.examples.Fib, kilim.examples.Tree 37 | */ 38 | 39 | public class Generator extends Continuation implements Iterator, Iterable { 40 | T nextVal; 41 | boolean done = false; 42 | 43 | public boolean hasNext() { 44 | if (nextVal == null) { 45 | if (done) 46 | return false; 47 | done = run(); 48 | return nextVal != null; 49 | } else { 50 | return true; 51 | } 52 | } 53 | 54 | public T next() { 55 | T ret; 56 | if (nextVal != null) { 57 | ret = nextVal; 58 | nextVal = null; 59 | return ret; 60 | } 61 | if (done) { 62 | throw new NoSuchElementException(); 63 | } 64 | done = run(); 65 | ret = nextVal; 66 | nextVal = null; 67 | return ret; 68 | } 69 | 70 | public void remove() { 71 | throw new AssertionError("Not Supported"); 72 | } 73 | 74 | public Iterator iterator() { 75 | return this; 76 | } 77 | 78 | public void yield(T val) throws Pausable { 79 | nextVal = val; 80 | Fiber.yield(); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/kilim/KilimClassLoader.java: -------------------------------------------------------------------------------- 1 | // Copyright 2011 by sriram - offered under the terms of the MIT License 2 | 3 | package kilim; 4 | 5 | /** 6 | * Extends Classloader just to have access to the (protected) findLoadedClass method 7 | */ 8 | public class KilimClassLoader extends ClassLoader { 9 | public KilimClassLoader() { 10 | super(KilimClassLoader.class.getClassLoader()); 11 | } 12 | 13 | 14 | public boolean isLoaded(String className) { 15 | return super.findLoadedClass(className) != null; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/kilim/KilimException.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim; 8 | 9 | 10 | public class KilimException extends RuntimeException { 11 | private static final long serialVersionUID = 7856831331381969854L; 12 | 13 | public KilimException(String msg) {super(msg);} 14 | } 15 | -------------------------------------------------------------------------------- /src/kilim/NotPausable.java: -------------------------------------------------------------------------------- 1 | // Copyright 2006 by sriram - offered under the terms of the MIT License 2 | 3 | package kilim; 4 | 5 | public class NotPausable extends RuntimeException { 6 | private static final long serialVersionUID = 1L; 7 | } 8 | -------------------------------------------------------------------------------- /src/kilim/PauseReason.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim; 8 | 9 | /** 10 | * @see Task#pause(PauseReason) 11 | */ 12 | public interface PauseReason { 13 | /** 14 | * True if the given task's reason for pausing is still valid. 15 | */ 16 | boolean isValid(Task t); 17 | } 18 | -------------------------------------------------------------------------------- /src/kilim/ServletHandler.java: -------------------------------------------------------------------------------- 1 | package kilim; 2 | 3 | import java.io.IOException; 4 | import javax.servlet.AsyncContext; 5 | import javax.servlet.ServletException; 6 | import javax.servlet.http.HttpServlet; 7 | import javax.servlet.http.HttpServletRequest; 8 | import javax.servlet.http.HttpServletResponse; 9 | 10 | 11 | 12 | public class ServletHandler extends HttpServlet { 13 | Iface handler; 14 | public ServletHandler(Iface handler) { this.handler = handler; } 15 | 16 | protected void service(final HttpServletRequest req,final HttpServletResponse resp) throws ServletException,IOException { 17 | final AsyncContext async = req.startAsync(); 18 | new kilim.Task() { 19 | public void execute() throws Pausable, Exception { 20 | try { 21 | String result = handler.handle(req,resp); 22 | if (result != null) resp.getOutputStream().print(result); 23 | } 24 | catch (Exception ex) { resp.sendError(500,"the server encountered an error"); } 25 | async.complete(); 26 | } 27 | }.start(); 28 | } 29 | 30 | 31 | public interface Iface { 32 | String handle(HttpServletRequest req,HttpServletResponse resp) throws Pausable, Exception; 33 | } 34 | 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/kilim/ShutdownException.java: -------------------------------------------------------------------------------- 1 | // Copyright 2010 by sriram - offered under the terms of the MIT License 2 | 3 | package kilim; 4 | 5 | public class ShutdownException extends Exception { 6 | private static final long serialVersionUID = 1L; 7 | 8 | public ShutdownException() { 9 | // TODO Auto-generated constructor stub 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/kilim/State.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim; 8 | 9 | /** 10 | * State is the super class for customized State objects generated 11 | * by ClassWeaver. For example, a customized state object may 12 | * look like this: 13 | *
14 |  * public final class kilim.S_O2I3 extends kilim.State{
15 |  *   public java.lang.Object f0, f1;
16 |  *   public int f2, f3, f4;
17 |  *   public kilim.S_O2I3();
18 |  * }
19 |  * 
20 | * This customized class contains slots for two objects and three 21 | * integers (its name is indicative of this aspect) and is used 22 | * as a canonical class to store any activation frame that needs 23 | * to store two objects and three ints. 24 | * 25 | */ 26 | 27 | public class State { 28 | public int pc; 29 | public Object self; 30 | } 31 | -------------------------------------------------------------------------------- /src/kilim/TaskDoneReason.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim; 8 | 9 | public class TaskDoneReason implements PauseReason { 10 | Object exitObj; 11 | TaskDoneReason(Object o) {exitObj = o;} 12 | 13 | public boolean isValid(Task t) { 14 | // When a task is done, it is reason to continue pausing 15 | return true; 16 | } 17 | 18 | public String toString() { 19 | return "Done. Exit msg = " + exitObj; 20 | } 21 | } -------------------------------------------------------------------------------- /src/kilim/TaskGroup.java: -------------------------------------------------------------------------------- 1 | // Copyright 2006 by sriram - offered under the terms of the MIT License 2 | 3 | package kilim; 4 | 5 | import java.util.ArrayList; 6 | import java.util.Collections; 7 | import java.util.HashSet; 8 | import java.util.List; 9 | 10 | public class TaskGroup extends Task { 11 | private Mailbox addedTasksMB = new Mailbox(); 12 | private Mailbox exitmb = new Mailbox(); 13 | private HashSet tasks = new HashSet(); 14 | 15 | public List results = Collections.synchronizedList(new ArrayList()); 16 | 17 | public void execute() throws Pausable { 18 | while (!tasks.isEmpty() || addedTasksMB.hasMessage()) { 19 | switch (Mailbox.select(addedTasksMB, exitmb)) { 20 | case 0: 21 | Task t = addedTasksMB.getnb(); 22 | t.informOnExit(exitmb); 23 | tasks.add(t); 24 | break; 25 | case 1: 26 | ExitMsg em = exitmb.getnb(); 27 | results.add(em); 28 | tasks.remove(em.task); 29 | break; 30 | } 31 | } 32 | exit(results); 33 | } 34 | 35 | @Override 36 | public ExitMsg joinb() { 37 | start(); 38 | return super.joinb(); 39 | } 40 | 41 | @Override 42 | public ExitMsg join() throws Pausable { 43 | start(); 44 | return super.join(); 45 | } 46 | 47 | public void add(Task t) { 48 | t.informOnExit(exitmb); 49 | addedTasksMB.putnb(t); // will wake up join if it is waiting. 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/kilim/YieldReason.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim; 8 | 9 | public class YieldReason implements PauseReason { 10 | public boolean isValid(Task t) { 11 | // Since a yield is not a reason to continue pausing, return false 12 | return false; 13 | } 14 | @Override 15 | public String toString() { 16 | return "yield"; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/kilim/analysis/BBList.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | package kilim.analysis; 7 | import java.util.ArrayList; 8 | 9 | /** 10 | * Just a convenient alias for ArrayList 11 | */ 12 | public class BBList extends ArrayList 13 | { 14 | private static final long serialVersionUID = -1768924113292685739L; 15 | public BBList() {} 16 | public BBList(int size) { 17 | super(size); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/kilim/analysis/ClassInfo.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | package kilim.analysis; 7 | 8 | public class ClassInfo { 9 | /** 10 | * fully qualified classname in a format suitable for Class.forName 11 | */ 12 | public String className; 13 | 14 | /** 15 | * bytecode for the class 16 | */ 17 | public byte[] bytes; 18 | 19 | public ClassInfo(String aClassName, byte[] aBytes) { 20 | className = aClassName.replace('/', '.'); 21 | // className = aClassName.replace('.', '/'); 22 | bytes = aBytes; 23 | } 24 | 25 | @Override 26 | public String toString() { 27 | return className; 28 | } 29 | 30 | @Override 31 | public int hashCode() { 32 | return className.hashCode(); 33 | } 34 | 35 | @Override 36 | public boolean equals(Object obj) { 37 | if (this == obj) { 38 | return true; 39 | } 40 | if ((obj instanceof ClassInfo) 41 | && ((ClassInfo)obj).className.equals(this.className)) { 42 | return true; 43 | } 44 | return false; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/kilim/analysis/ClassWriter.java: -------------------------------------------------------------------------------- 1 | // Copyright 2013 by Jason Pell - offered under the terms of the MIT License 2 | 3 | package kilim.analysis; 4 | 5 | import kilim.mirrors.Detector; 6 | 7 | public class ClassWriter extends org.objectweb.asm.ClassWriter { 8 | private final Detector detector; 9 | 10 | 11 | public ClassWriter(final int flags, final Detector detector) { 12 | super(flags); 13 | this.detector = detector; 14 | } 15 | 16 | protected String getCommonSuperClass(final String type1, final String type2) { 17 | try { 18 | return detector.commonSuperType(type1, type2); 19 | } catch (kilim.mirrors.ClassMirrorNotFoundException e) { 20 | return "java/lang/Object"; 21 | } 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/kilim/analysis/IncompatibleTypesException.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.analysis; 8 | 9 | public class IncompatibleTypesException extends Exception { 10 | public IncompatibleTypesException(String message) { 11 | super(message); 12 | } 13 | private static final long serialVersionUID = 1270645277746840738L; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/kilim/analysis/KilimContext.java: -------------------------------------------------------------------------------- 1 | // copyright 2016 nqzero - offered under the terms of the MIT License 2 | package kilim.analysis; 3 | 4 | import kilim.mirrors.CachedClassMirrors; 5 | import kilim.mirrors.Detector; 6 | 7 | public class KilimContext { 8 | static public KilimContext DEFAULT = new KilimContext(); 9 | 10 | public Detector detector; 11 | 12 | public KilimContext() { 13 | detector = new Detector(new CachedClassMirrors()); 14 | } 15 | public KilimContext(CachedClassMirrors mirrors) { 16 | detector = new Detector(mirrors); 17 | } 18 | 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/kilim/analysis/NopInsn.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.analysis; 8 | 9 | import static org.objectweb.asm.Opcodes.NOP; 10 | 11 | import java.util.Map; 12 | 13 | import org.objectweb.asm.MethodVisitor; 14 | import org.objectweb.asm.tree.AbstractInsnNode; 15 | 16 | class NopInsn extends AbstractInsnNode { 17 | public NopInsn() { 18 | super(NOP); 19 | } 20 | 21 | public int getType() { 22 | return 0; 23 | } 24 | 25 | @Override 26 | public void accept(MethodVisitor mv) { 27 | // Do nothing 28 | } 29 | 30 | 31 | @Override 32 | public String toString() { 33 | return "NOP"; 34 | } 35 | 36 | @Override 37 | public AbstractInsnNode clone(@SuppressWarnings("rawtypes") Map labels) { 38 | return new NopInsn(); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/kilim/analysis/Range.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.analysis; 8 | 9 | /** 10 | * Used by catch handlers to handle overlapping ranges 11 | * 12 | */ 13 | public class Range { 14 | int from; 15 | int to; 16 | 17 | public Range(int aFrom, int aTo) { 18 | from = aFrom; 19 | to = aTo; 20 | } 21 | 22 | static Range intersect(int a1, int e1, int a2, int e2) { 23 | // a2 lies between a1 and e1 or a1 between a2 and e2 24 | // all comparisons are inclusive of endpoints 25 | assert a1 <= e1 && a2 <= e2; 26 | int a; 27 | if (a1 <= a2 && a2 <= e1) { 28 | a = a2; 29 | } else if (a2 <= a1 && a1 <= e2) { 30 | a = a1; 31 | } else { 32 | return null; 33 | } 34 | return new Range(a, e1 < e2 ? e1 : e2); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/kilim/analysis/Utils.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.analysis; 8 | 9 | /** 10 | * Simple string utils for pretty printing support 11 | * 12 | */ 13 | public class Utils { 14 | public static String indentStr = ""; 15 | public static String spaces = " "; 16 | 17 | public static void indentWith(String s) { 18 | indentStr = indentStr + s; 19 | } 20 | 21 | public static void indent(int numSpaces) { 22 | indentWith(spaces.substring(0, numSpaces)); 23 | } 24 | 25 | public static void dedent(int numSpaces) { 26 | indentStr = indentStr.substring(0, indentStr.length() - numSpaces); 27 | } 28 | 29 | public static String format(String s) { 30 | if (indentStr.length() == 0) 31 | return s; 32 | int i = s.indexOf('\n'); // i is always the index of newline 33 | if (i >= 0) { 34 | StringBuffer sb = new StringBuffer(100); 35 | sb.append(indentStr); // leading indent 36 | int prev = 0; // prev value of i in loop 37 | do { 38 | // copy from prev to i (including \n) 39 | sb.append(s, prev, i + 1); 40 | // add indentation wherever \n occurs 41 | sb.append(indentStr); 42 | prev = i + 1; 43 | if (prev >= s.length()) 44 | break; 45 | i = s.indexOf('\n', prev); 46 | } while (i != -1); 47 | // copy left over chars from the last segment 48 | sb.append(s, prev, s.length()); 49 | return sb.toString(); 50 | } else { 51 | return indentStr + s; 52 | } 53 | } 54 | 55 | public static void resetIndentation() { 56 | indentStr = ""; 57 | } 58 | 59 | public static void p(String s) { 60 | System.out.print(format(s)); 61 | } 62 | 63 | public static void pn(String s) { 64 | System.out.println(format(s)); 65 | } 66 | 67 | public static void pn(int i) { 68 | System.out.println(format("" + i)); 69 | } 70 | 71 | public static void pn() { 72 | System.out.println(); 73 | } 74 | 75 | public static void pn(Object o) { 76 | pn((o == null) ? "null" : o.toString()); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/kilim/bench: -------------------------------------------------------------------------------- 1 | ../../bench/kilim/bench -------------------------------------------------------------------------------- /src/kilim/concurrent/PaddedEventSubscriber.java: -------------------------------------------------------------------------------- 1 | // Copyright 2014 nilangshah - offered under the terms of the MIT License 2 | 3 | package kilim.concurrent; 4 | 5 | import kilim.EventSubscriber; 6 | 7 | abstract class EventSubCellPrePad { 8 | long p0, p1, p2, p3, p4, p5, p6; 9 | } 10 | 11 | abstract class EventSubCellValue extends EventSubCellPrePad { 12 | public EventSubscriber value; 13 | } 14 | 15 | public class PaddedEventSubscriber extends EventSubCellValue { 16 | int i0; 17 | long p10, p11, p12, p13, p14, p15, p16; 18 | 19 | public PaddedEventSubscriber() { 20 | 21 | } 22 | 23 | public EventSubscriber get() { 24 | return value; 25 | } 26 | 27 | public void set(EventSubscriber e) { 28 | value = e; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/kilim/concurrent/UnsafeAccess.java: -------------------------------------------------------------------------------- 1 | // Copyright 2014 by nilangshah - offered under the terms of the MIT License 2 | 3 | package kilim.concurrent; 4 | 5 | import java.lang.reflect.Field; 6 | 7 | import sun.misc.Unsafe; 8 | 9 | @SuppressWarnings("restriction") 10 | public class UnsafeAccess { 11 | @SuppressWarnings("restriction") 12 | public static final Unsafe UNSAFE; 13 | static { 14 | try { 15 | @SuppressWarnings("restriction") 16 | Field field = Unsafe.class.getDeclaredField("theUnsafe"); 17 | 18 | field.setAccessible(true); 19 | 20 | UNSAFE = (Unsafe) field.get(null); 21 | } catch (Exception e) { 22 | throw new RuntimeException(e); 23 | } 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/kilim/concurrent/VolatileBoolean.java: -------------------------------------------------------------------------------- 1 | // Copyright 2014 nilangshah - offered under the terms of the MIT License 2 | 3 | package kilim.concurrent; 4 | 5 | import static kilim.concurrent.UnsafeAccess.UNSAFE; 6 | 7 | abstract class VolatileBooleanPrePad { 8 | // long p0, p1, p2, p3, p4, p5, p6; 9 | } 10 | 11 | abstract class VolatileBooleanValue extends VolatileBooleanPrePad { 12 | protected volatile int value; 13 | } 14 | 15 | @SuppressWarnings("restriction") 16 | public final class VolatileBoolean extends VolatileBooleanValue { 17 | // long p10, p11, p12, p13, p14, p15, p16; 18 | private final static long VALUE_OFFSET; 19 | static { 20 | try { 21 | VALUE_OFFSET = UNSAFE.objectFieldOffset(VolatileBooleanValue.class.getDeclaredField("value")); 22 | } catch (NoSuchFieldException e) { 23 | throw new RuntimeException(e); 24 | } 25 | } 26 | 27 | public VolatileBoolean() { 28 | this(false); 29 | } 30 | 31 | public VolatileBoolean(boolean v) { 32 | lazySet(v); 33 | } 34 | 35 | public void lazySet(boolean newV) { 36 | int v = newV ? 1 : 0; 37 | UNSAFE.putOrderedInt(this, VALUE_OFFSET, v); 38 | } 39 | 40 | public void set(boolean newV) { 41 | value = newV ? 1 : 0; 42 | } 43 | 44 | public boolean get() { 45 | return value != 0; 46 | } 47 | 48 | public final boolean compareAndSet(boolean expect, boolean update) { 49 | int e = expect ? 1 : 0; 50 | int u = update ? 1 : 0; 51 | return UNSAFE.compareAndSwapInt(this, VALUE_OFFSET, e, u); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/kilim/concurrent/VolatileLongCell.java: -------------------------------------------------------------------------------- 1 | // Copyright 2014 nilangshah - offered under the terms of the MIT License 2 | 3 | package kilim.concurrent; 4 | 5 | import static kilim.concurrent.UnsafeAccess.UNSAFE; 6 | 7 | abstract class VolatileLongCellPrePad { 8 | volatile long p0, p1, p2, p3, p4, p5, p6; 9 | } 10 | 11 | abstract class VolatileLongCellValue extends VolatileLongCellPrePad { 12 | protected volatile long value; 13 | } 14 | 15 | @SuppressWarnings("restriction") 16 | public final class VolatileLongCell extends VolatileLongCellValue { 17 | volatile long p10, p11, p12, p13, p14, p15, p16; 18 | private final static long VALUE_OFFSET; 19 | static { 20 | try { 21 | VALUE_OFFSET = UNSAFE.objectFieldOffset(VolatileLongCellValue.class 22 | .getDeclaredField("value")); 23 | } catch (NoSuchFieldException e) { 24 | throw new RuntimeException(e); 25 | } 26 | } 27 | 28 | public VolatileLongCell() { 29 | this(0L); 30 | } 31 | 32 | public VolatileLongCell(long v) { 33 | lazySet(v); 34 | } 35 | 36 | public void lazySet(long v) { 37 | UNSAFE.putOrderedLong(this, VALUE_OFFSET, v); 38 | } 39 | 40 | public void set(long v) { 41 | this.value = v; 42 | } 43 | 44 | public long get() { 45 | return this.value; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/kilim/concurrent/VolatileReferenceCell.java: -------------------------------------------------------------------------------- 1 | // Copyright 2014 nilangshah - offered under the terms of the MIT License 2 | 3 | package kilim.concurrent; 4 | 5 | import static kilim.concurrent.UnsafeAccess.UNSAFE; 6 | 7 | abstract class VolatileReferenceCellValue extends VolatileLongCellPrePad { 8 | protected volatile V value; 9 | } 10 | 11 | @SuppressWarnings("restriction") 12 | public class VolatileReferenceCell extends VolatileReferenceCellValue { 13 | volatile long p10, p11, p12, p13, p14, p15, p16; 14 | private static final long valueOffset; 15 | 16 | static { 17 | try { 18 | valueOffset = UNSAFE 19 | .objectFieldOffset(VolatileReferenceCellValue.class 20 | .getDeclaredField("value")); 21 | } catch (Exception ex) { 22 | throw new Error(ex); 23 | } 24 | } 25 | 26 | public VolatileReferenceCell(V initialValue) { 27 | value = initialValue; 28 | } 29 | 30 | public VolatileReferenceCell() { 31 | } 32 | 33 | public final V get() { 34 | return value; 35 | } 36 | 37 | public final void set(V newValue) { 38 | value = newValue; 39 | } 40 | 41 | public final void lazySet(V newValue) { 42 | UNSAFE.putOrderedObject(this, valueOffset, newValue); 43 | } 44 | 45 | public final boolean compareAndSet(V expect, V update) { 46 | return UNSAFE.compareAndSwapObject(this, valueOffset, expect, update); 47 | } 48 | 49 | public final boolean weakCompareAndSet(V expect, V update) { 50 | return UNSAFE.compareAndSwapObject(this, valueOffset, expect, update); 51 | } 52 | 53 | public final V getAndSet(V newValue) { 54 | while (true) { 55 | V x = get(); 56 | if (compareAndSet(x, newValue)) 57 | return x; 58 | } 59 | } 60 | 61 | public String toString() { 62 | return String.valueOf(get()); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/kilim/examples/Chain.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.examples; 8 | 9 | import kilim.*; 10 | /** 11 | * Set up a chain of tasks. Each task knows about its mailbox and 12 | * that of the next in the chain, but is not given the other tasks 13 | * ref. 14 | * The main thread pushes an empty StringBuffer into the first task's 15 | * mailbox, which writes "hello" into the buffer and passes the 16 | * modified StringBuffer on to the next task, and so on. The last 17 | * task appends "world", prints it out and exits. 18 | * 19 | * [compile] javac -d ./classes Chain.java 20 | * [weave] java kilim.tools.Weave -d ./wclasses kilim.examples.Chain 21 | * [run] java -cp ./wclasses:./classes:$CLASSPATH kilim.examples.Chain 22 | * @author ram 23 | */ 24 | public class Chain extends Task { 25 | Mailbox mymb, nextmb; 26 | public Chain(Mailbox mb, Mailbox next) { 27 | mymb = mb; 28 | nextmb = next; 29 | } 30 | 31 | 32 | public void execute() throws Pausable{ 33 | while(true) { 34 | StringBuffer sb = mymb.get(); 35 | if (nextmb == null) { 36 | System.out.print(sb); 37 | System.out.println("world"); 38 | System.exit(0); 39 | } else { 40 | sb.append("hello "); 41 | nextmb.put(sb); 42 | } 43 | } 44 | } 45 | 46 | public static void main(String args[]) { 47 | int n = args.length == 0 ? 10 : Integer.parseInt(args[0]); 48 | Mailbox mb = new Mailbox(); 49 | Mailbox nextms = null; 50 | for (int i = 0; i < n; i++) { 51 | new Chain(mb, nextms).start(); 52 | nextms = mb; 53 | mb = new Mailbox(); 54 | } 55 | nextms.putnb(new StringBuffer()); 56 | Task.idledown(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/kilim/examples/Ex.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.examples; 8 | 9 | import kilim.Mailbox; 10 | import kilim.Pausable; 11 | import kilim.Task; 12 | 13 | /** 14 | * Spawn a task, communicate through a shared mailbox. The task's 15 | * termination is knowm through another mailbox. 16 | * 17 | * The structure of this class is not much different from a Thread 18 | * version that uses PipedInput/OutputStreams (Task instead of Thread, 19 | * execute() instead of run(), and typed, buffered mailboxes instead 20 | * of pipes. 21 | * 22 | * [compile] javac -d ./classes Ex.java 23 | * [weave] java kilim.tools.Weave -d ./classes kilim.examples.Ex 24 | * [run] java -cp ./classes:./classes:$CLASSPATH kilim.examples.Ex 25 | */ 26 | public class Ex extends Task { 27 | static Mailbox mb = new Mailbox(); 28 | 29 | public static void main(String[] args) throws Exception { 30 | new Ex().start(); 31 | Thread.sleep(10); 32 | mb.putnb("Hello "); 33 | mb.putnb("World\n"); 34 | mb.putnb("done"); 35 | Task.idledown(); 36 | } 37 | 38 | /** 39 | * The entry point. mb.get() is a blocking call that yields 40 | * the thread ("pausable") 41 | */ 42 | 43 | public void execute() throws Pausable{ 44 | for (int i = 0; i < 10; i++) { 45 | try { 46 | foo(i); 47 | } catch (Exception ignore) { 48 | System.out.println(i); 49 | foo(++i); 50 | } 51 | } 52 | } 53 | private void foo(int i) throws Pausable { 54 | if (i %2 == 0) { 55 | Task.sleep(100); 56 | } else { 57 | throw new RuntimeException(); 58 | } 59 | 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/kilim/examples/Fib.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.examples; 8 | 9 | import java.math.BigInteger; 10 | 11 | import kilim.Generator; 12 | import kilim.Pausable; 13 | 14 | /** 15 | * This example prints the nth Fibonacci number. 16 | * 17 | * It illustrates a generator, which is part iterator, part task. It returns the next object 'yielded' by its execute 18 | * method. The difference between a generator and a task is that the former is invoked by the caller synchronously on 19 | * the caller's stack; it is not scheduled in a separate thread. 20 | */ 21 | public class Fib extends Generator { 22 | 23 | public static void main(String[] args) { 24 | int n; 25 | if (args.length == 0) { 26 | System.out.println("java kilim.examples.Fib for the n_th fibonacci number"); 27 | System.out.println(" using default ..."); 28 | n = 19; 29 | } 30 | else 31 | n = Integer.parseInt(args[0]); 32 | Fib fib = new Fib(); 33 | 34 | // Iterate through and waste the first n fibonacci numbers 35 | for (int i = 0; i < n; i++) { 36 | fib.next(); 37 | } 38 | // .. and print the last one 39 | System.out.println("" + n + " : " + fib.next()); 40 | } 41 | 42 | public void execute() throws Pausable { 43 | BigInteger i = BigInteger.ZERO; 44 | BigInteger j = BigInteger.ONE; 45 | while (true) { 46 | // / NOTE: Generator yields a result 47 | // / j is now available to the caller of this generator's next() method. 48 | yield(j); 49 | BigInteger f = i.add(j); 50 | i = j; 51 | j = f; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/kilim/examples/Group.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.examples; 8 | 9 | import kilim.Pausable; 10 | import kilim.Task; 11 | import kilim.TaskGroup; 12 | 13 | public class Group { 14 | public static void main(String[] args) { 15 | TaskGroup tg = new TaskGroup(); 16 | tg.add(new GroupTask().start()); 17 | tg.add(new GroupTask().start()); 18 | tg.joinb(); 19 | System.exit(0); 20 | } 21 | 22 | static class GroupTask extends Task { 23 | public void execute() throws Pausable { 24 | System.out.println("Task #" + id + "sleeping"); 25 | Task.sleep(1000); 26 | System.out.println("Task #" + id + "done"); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/kilim/examples/HeapBlast.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.examples; 8 | 9 | import java.util.Random; 10 | import kilim.timerservice.Timer; 11 | import kilim.timerservice.TimerPriorityHeap; 12 | 13 | public class HeapBlast { 14 | 15 | 16 | static Random rand = new Random(0L); 17 | int num = 1000; 18 | int size = 0; 19 | static int ndone; 20 | 21 | Timer [] sorted = new Timer[num]; 22 | Timer [] polled = new Timer[num]; 23 | 24 | TimerPriorityHeap heap; 25 | 26 | 27 | void claim(boolean test) { 28 | ndone++; 29 | if (! test) 30 | throw new RuntimeException(); 31 | } 32 | 33 | void poll() { 34 | if (size==0) return; 35 | Timer t1 = heap.peek(); 36 | heap.poll(); 37 | int ii; 38 | for (ii = 0; sorted[ii] != t1; ii++) 39 | claim(polled[ii] != null); 40 | polled[ii] = t1; 41 | size--; 42 | } 43 | 44 | void add() { 45 | if (size==num) return; 46 | int index; 47 | while (polled[index = rand.nextInt(num)]==null) {} 48 | heap.add(polled[index]); 49 | polled[index] = null; 50 | size++; 51 | } 52 | 53 | HeapBlast() { 54 | for (int ii=0; ii < num; ii++) 55 | (polled[ii] = sorted[ii] = new Timer(null)).setTimer(ii); 56 | } 57 | 58 | void build() { 59 | heap = new TimerPriorityHeap(); 60 | for (int ii=0; ii < num; ii++) 61 | (polled[ii] = sorted[ii] = new Timer(null)).setTimer(ii); 62 | size = 0; 63 | test(); 64 | } 65 | 66 | void step(int target) { 67 | boolean flip = rand.nextInt(16) > 13; 68 | boolean up = (target >= size) ^ flip; 69 | if (up) add(); 70 | else poll(); 71 | } 72 | 73 | void test() { 74 | for (int ii=0; ii < 1000; ii++) { 75 | boolean mode = rand.nextInt(16) > 7; 76 | int target = mode ? size+rand.nextInt(15)-7 : 1+rand.nextInt(num); 77 | if (mode) 78 | for (int jj=0; jj < 100; jj++) step(target); 79 | else 80 | while (size != target) step(target); 81 | } 82 | } 83 | 84 | 85 | public static void main(String[] args) throws Exception { 86 | HeapBlast blast = new HeapBlast(); 87 | 88 | for (int ii=0; ii < 100; ii++) 89 | blast.build(); 90 | System.out.println("completed timers: " + ndone); 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /src/kilim/examples/Reflect.java: -------------------------------------------------------------------------------- 1 | // Copyright 2010 by sriram - offered under the terms of the MIT License 2 | 3 | package kilim.examples; 4 | 5 | import java.lang.reflect.Method; 6 | 7 | import kilim.Pausable; 8 | import kilim.Task; 9 | 10 | public class Reflect extends Task { 11 | @Override 12 | public void execute() throws Pausable, Exception { 13 | int n = test(); 14 | System.out.println("test (normal invocation of instance method): " + n); 15 | // Invoking test() via reflection 16 | Method method = Reflect.class.getDeclaredMethod("test", new Class[0]); 17 | Object ret = Task.invoke(method, this, /* no args */(Object[])null); 18 | System.out.println("test (reflect invocation of instance method): " + ret); 19 | 20 | n = static_test(); 21 | System.out.println("test (normal invocation of static method): " + n); 22 | // Invoking test() via reflection 23 | method = Reflect.class.getDeclaredMethod("static_test", new Class[0]); 24 | ret = Task.invoke(method, /* target = */ null, /* no args */(Object[])null); 25 | System.out.println("test (reflect invocation of static method): " + ret); 26 | System.exit(0); 27 | } 28 | 29 | public int test() throws Pausable { 30 | int m = 10; 31 | for (int i = 0; i < 2; i++) { // Force multiple yields 32 | Task.sleep(100); 33 | m *= 2; 34 | } 35 | return m; // must return 40 if all goes well. 36 | } 37 | 38 | public static int static_test() throws Pausable { 39 | int m = 10; 40 | for (int i = 0; i < 2; i++) { // Force multiple yields 41 | Task.sleep(100); 42 | m *= 2; 43 | } 44 | return m; // must return 40 if all goes well. 45 | } 46 | 47 | 48 | public static void main(String args[]) { 49 | Reflect ref = new Reflect(); 50 | ref.start(); 51 | ref.joinb(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/kilim/examples/SimpleTask.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.examples; 8 | 9 | import kilim.Mailbox; 10 | import kilim.Pausable; 11 | import kilim.Task; 12 | 13 | /** 14 | * Spawn a task, communicate through a shared mailbox. The task's 15 | * termination is known through another mailbox. 16 | * 17 | * The structure of this class is not much different from a Thread 18 | * version that uses PipedInput/OutputStreams (Task instead of Thread, 19 | * execute() instead of run(), and typed, buffered mailboxes instead 20 | * of pipes). 21 | * 22 | * [compile] javac -d ./classes SimpleTask.java 23 | * [weave] java kilim.tools.Weave -d ./classes kilim.examples.SimpleTask 24 | * [run] java -cp ./classes:./classes:$CLASSPATH kilim.examples.SimpleTask 25 | */ 26 | public class SimpleTask extends Task { 27 | static Mailbox mb = new Mailbox(); 28 | 29 | public static void main(String[] args) throws Exception { 30 | new SimpleTask().start(); 31 | Thread.sleep(10); 32 | mb.putnb("Hello "); 33 | mb.putnb("World\n"); 34 | mb.putnb("done"); 35 | idledown(); 36 | } 37 | 38 | /** 39 | * The entry point. mb.get() is a blocking call that yields 40 | * the thread ("pausable") 41 | */ 42 | 43 | public void execute() throws Pausable{ 44 | while (true) { 45 | String s = mb.get(); 46 | if (s.equals("done")) break; 47 | System.out.print(s); 48 | } 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/kilim/examples/SimpleTask2.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.examples; 8 | 9 | import kilim.ExitMsg; 10 | import kilim.Mailbox; 11 | import kilim.Pausable; 12 | import kilim.Task; 13 | 14 | /** 15 | * A slight extension to SimpleTask. This 16 | * 17 | * [compile] javac -d ./classes SimpleTask2.java 18 | * [weave] java kilim.tools.Weave -d ./classes kilim.examples.SimpleTask 19 | * [run] java -cp ./classes:./classes:$CLASSPATH kilim.examples.SimpleTask2 20 | */ 21 | public class SimpleTask2 extends Task { 22 | static Mailbox mb = new Mailbox(); 23 | static Mailbox exitmb = new Mailbox(); 24 | 25 | public static void main(String[] args) throws Exception { 26 | Task t = new SimpleTask2().start(); 27 | t.informOnExit(exitmb); 28 | mb.putnb("Hello "); 29 | mb.putnb("World\n"); 30 | mb.putnb("done"); 31 | 32 | exitmb.getb(); 33 | System.exit(0); 34 | } 35 | 36 | /** 37 | * The entry point. mb.get() is a blocking call that yields 38 | * the thread ("pausable") 39 | */ 40 | 41 | public void execute() throws Pausable{ 42 | while (true) { 43 | String s = mb.get(); 44 | if (s.equals("done")) break; 45 | System.out.print(s); 46 | } 47 | Task.exit(0); // Strictly optional. 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/kilim/examples/Spawn.java: -------------------------------------------------------------------------------- 1 | // copyright 2016 nqzero - offered under the terms of the MIT License 2 | 3 | package kilim.examples; 4 | 5 | import kilim.Mailbox; 6 | import kilim.Pausable; 7 | import kilim.Task; 8 | 9 | /** 10 | * Spawn example with one consumer, ten producers 11 | */ 12 | public class Spawn { 13 | public static void main(String[] args) throws Exception { 14 | // mb is captured by all lambdas. 15 | Mailbox mb = new Mailbox(); 16 | 17 | //Consumer 18 | Task.spawn( () -> { 19 | while (true) { 20 | String s = mb.get(); // mb captured from environment. 21 | System.out.println(s); 22 | } 23 | }); 24 | // Producers 25 | for (int i = 0; i < 10; i++) { 26 | final int fi = i; // Need a 'final' i to pass to closure 27 | Task.fork( () -> { 28 | mb.put("Hello from " + fi); // mb and fi captured from environment 29 | }); 30 | } 31 | Task.idledown(); 32 | } 33 | 34 | // an example showing pausable chaining with exception inference 35 | private void exampleUsage() throws Pausable, java.io.EOFException, java.io.IOException { 36 | Pausable.apply(new Task.Spawn(), 37 | t -> t.start(), 38 | t -> { throw new java.io.EOFException(); }, 39 | t -> { throw new java.io.IOException(); }); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/kilim/examples/TimedTask.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.examples; 8 | 9 | import kilim.ExitMsg; 10 | import kilim.Mailbox; 11 | import kilim.Pausable; 12 | import kilim.Task; 13 | 14 | /** 15 | * Creates lots of tasks that print stuff, sleep, then wake up and print more. 16 | * 17 | * [compile] javac -d ./classes TimedTask.java 18 | * [weave] java kilim.tools.Weave -d ./wlasses kilim.examples.TimedTask 19 | * [run] java -cp ./wlasses:./classes:$CLASSPATH kilim.examples.TimedTask 20 | * 21 | * @author sriram@malhar.net 22 | */ 23 | public class TimedTask extends Task { 24 | public static void main(String[] args) throws Exception { 25 | int numTasks = (args.length > 0) ? Integer.parseInt(args[0]) : 100; 26 | Mailbox exitmb= new Mailbox (); 27 | 28 | for (int i = 0; i < numTasks; i++) { 29 | new TimedTask().start().informOnExit(exitmb); 30 | } 31 | 32 | for (int i = 0; i < numTasks; i++) { 33 | exitmb.getb(); 34 | } 35 | 36 | System.exit(0); 37 | } 38 | 39 | public void execute() throws Pausable { 40 | System.out.println("Task #" + id() + " going to sleep ..."); 41 | Task.sleep(2000); 42 | System.out.println(" Task #" + id() + " waking up"); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/kilim/examples/TimerBlast.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.examples; 8 | 9 | import java.util.concurrent.atomic.AtomicInteger; 10 | import kilim.Pausable; 11 | import kilim.Task; 12 | 13 | /* 14 | 15 | TimerBlast and TimerBlast2 are examples that help reproduce race conditions 16 | run them in a loop while simultaneously taxing the cpu eg with 2 maven builds of other projects looping 17 | TimerBlast should alternate between "hello world" and "..." 18 | under heavy external load it will miss a bunch of "hello worlds" 19 | 20 | TimerBlast2 should take on the order of a second to print each line 21 | under heavy external load it will hang 22 | attach a debugger and explore the conditions causing the task to not complete 23 | 24 | */ 25 | 26 | public class TimerBlast extends Task { 27 | static AtomicInteger cnt = new AtomicInteger(); 28 | 29 | 30 | 31 | public static class Tick extends Task { 32 | public void dive(int depth) throws Pausable { 33 | if (depth==0) Task.sleep(200); 34 | else dive(depth-1); 35 | } 36 | public void execute() throws Pausable { 37 | for (long ii=0, t1=0, t2=0; ii < 30; ii++, t1=t2) { 38 | dive(30); 39 | System.out.println("hello world"); 40 | } 41 | } 42 | 43 | } 44 | 45 | public static void main(String[] args) throws Exception { 46 | int num = 1000; 47 | 48 | for (int ii=0; ii < 10; ii++) new TimerBlast().start(); 49 | Thread.sleep(200); 50 | new Tick().start(); 51 | Thread.sleep(190); 52 | for (int ii=0; ii < num; ii++) new TimerBlast().start(); 53 | 54 | for (int ii=0; ii < 30; ii++) { 55 | System.out.println("..."); 56 | Thread.sleep(200); 57 | } 58 | 59 | 60 | idledown(); 61 | System.out.println(cnt.get()); 62 | } 63 | 64 | public void execute() throws Pausable{ 65 | Task.sleep(4000); 66 | cnt.incrementAndGet(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/kilim/examples/Tree.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.examples; 8 | import kilim.Generator; 9 | import kilim.Pausable; 10 | 11 | /** 12 | * This example illustrates two 'generators' that walk a tree, one in pre-order 13 | * and another in post-order. 14 | * 15 | * A generator is an iterator that generates a value (in this 16 | * case the nodes of the tree) each time its execute() method 17 | * 'yields' a value. 18 | * 19 | * Also, @see kilim.examples.Fib 20 | */ 21 | 22 | public class Tree { 23 | public String _val; 24 | Tree _left; 25 | Tree _right; 26 | 27 | public static void main(String[] args) { 28 | Tree t = new Tree("root", 29 | new Tree("a", 30 | new Tree("a1"), 31 | new Tree("a2")), 32 | new Tree("b", 33 | new Tree ("b1"), 34 | new Tree ("b2"))); 35 | 36 | System.out.println("Pre-order traversal:"); 37 | for (String s: new Pre(t)) { 38 | System.out.println(s); 39 | } 40 | 41 | System.out.println("Post-order traversal"); 42 | for (String s: new Post(t)) { 43 | System.out.println(s); 44 | } 45 | } 46 | 47 | Tree(String s) {_val = s;} 48 | 49 | Tree(String s, Tree l, Tree r) {this(s); _left = l; _right = r;} 50 | } 51 | 52 | class Pre extends Generator { 53 | Tree _t; 54 | Pre(Tree t) {_t = t;} 55 | 56 | public void execute() throws Pausable{ 57 | walk(_t); 58 | } 59 | 60 | void walk(Tree t) throws Pausable { 61 | if (t == null) return; 62 | yield(t._val); 63 | walk(t._left); 64 | walk(t._right); 65 | } 66 | } 67 | 68 | class Post extends Generator { 69 | Tree _t; 70 | Post(Tree t) {_t = t;} 71 | 72 | public void execute() throws Pausable { 73 | walk(_t); 74 | } 75 | 76 | void walk(Tree t) throws Pausable { 77 | if (t == null) return; 78 | walk(t._left); 79 | walk(t._right); 80 | yield(t._val); 81 | } 82 | } -------------------------------------------------------------------------------- /src/kilim/examples/Userdata.java: -------------------------------------------------------------------------------- 1 | // copyright 2016 nqzero - offered under the terms of the MIT License 2 | 3 | package kilim.examples; 4 | 5 | import java.util.stream.Stream; 6 | import kilim.Pausable; 7 | import kilim.Task; 8 | 9 | /* 10 | test of a number of ways of invoking a method that are or look similar to SAMs 11 | added for: https://github.com/kilim/kilim/issues/38 12 | 13 | also shows off Kilim.trampoline() - ie, this class can be run with or without weaving 14 | if it hasn't been woven, it will automatically call the runtime weaver 15 | */ 16 | public class Userdata extends Task { 17 | Eats1 eats1 = new Eats1Impl(); 18 | Eats2 eats2 = new Eats2(); 19 | 20 | public interface Eats1 { 21 | public static String stuff(String foo) { return foo + "-stuff"; } 22 | public void insert1(int kfood) throws Pausable; 23 | } 24 | public static class Eats1Impl implements Eats1 { 25 | public void insert1(int kfood) throws Pausable { System.out.println("gah"); } 26 | } 27 | public static class Eats2 { 28 | public void insert1(int kfood) throws Pausable { System.out.println("foo"); } 29 | public void insert2(int kfood) throws Pausable {} 30 | } 31 | public static class Eats3 { 32 | public void insert1(int kfood) throws Pausable { System.out.println("bar"); } 33 | } 34 | public interface Eats4 { 35 | public static String fluff(String foo) { return foo + "-fluff"; } 36 | public void insert1(int kfood) throws Pausable; 37 | } 38 | public interface Eats5 extends Eats4 { 39 | public static void buff(int kfood) throws Pausable { System.out.println(Eats4.fluff("fox-"+kfood)); } 40 | } 41 | public static void eater(Eats4 eat,int kfood) throws Pausable { 42 | eat.insert1(kfood); 43 | } 44 | 45 | public void execute() throws kilim.Pausable { 46 | eats1.insert1(0); 47 | System.out.println(Eats1.stuff("funky")); 48 | eats2.insert1(0); 49 | new Eats3().insert1(0); 50 | eater(kfood -> System.out.println("lam"), 0); 51 | Eats4.fluff("marshmallow"); 52 | Eats5.buff(5); 53 | Stream.of(0,1,2,3,4).forEach(System.out::println); 54 | System.exit(0); 55 | } 56 | 57 | /** 58 | * start the userdata task 59 | * this entry point supports automatic runtime weaving 60 | * if the code hasn't been woven when invoked, it will trampoline off the WeavingClassLoader 61 | */ 62 | public static void main(String [] args) { 63 | if (kilim.tools.Kilim.trampoline(true,args)) return; 64 | new Userdata().start(); 65 | Task.idledown(); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/kilim/http/HttpMsg.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.http; 8 | 9 | import java.nio.ByteBuffer; 10 | 11 | public class HttpMsg { 12 | ByteBuffer buffer; 13 | } 14 | -------------------------------------------------------------------------------- /src/kilim/http/IntList.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.http; 8 | 9 | public class IntList { 10 | public int[] array; 11 | public int numElements; 12 | public IntList(int initialSize) { 13 | array = new int[initialSize]; 14 | } 15 | public IntList() {this(10);} 16 | 17 | public void add(int element) { 18 | if (numElements == array.length) { 19 | array = (int[]) Utils.growArray(array, array.length * 3 / 2 ); 20 | } 21 | array[numElements++] = element; 22 | } 23 | 24 | public int get(int index) { 25 | return array[index]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/kilim/http/KeyValues.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.http; 8 | 9 | 10 | /** 11 | * A low overhead map to avoid creating too many objects (Entry objects and iterators etc) 12 | */ 13 | public class KeyValues { 14 | public String[] keys; 15 | public String[] values; 16 | public int count; 17 | 18 | public KeyValues() {this(5);} 19 | public KeyValues(int size) { 20 | keys = new String[size]; 21 | values = new String[size]; 22 | } 23 | 24 | /** 25 | * @param key 26 | * @return value for the given key. 27 | */ 28 | public String get(String key) { 29 | int i = indexOf(key); 30 | return i == -1 ? "" : values[i]; 31 | } 32 | 33 | public int indexOf(String key) { 34 | int len = count; 35 | for (int i = 0; i < len; i++) { 36 | if (keys[i].equals(key)) { 37 | return i; 38 | } 39 | } 40 | return -1; 41 | } 42 | 43 | /** 44 | * add/replace key value pair. 45 | * @param key 46 | * @param value 47 | * @return old value 48 | */ 49 | public void put(String key, String value) { 50 | int i = indexOf(key); 51 | if (i == -1) { 52 | if (count == keys.length) { 53 | keys = (String[]) Utils.growArray(keys, count * 2); 54 | values = (String[]) Utils.growArray(values, count * 2); 55 | } 56 | keys[count] = key; 57 | values[count] = value; 58 | count++; 59 | } else { 60 | values[i] = value; 61 | } 62 | } 63 | 64 | @Override 65 | public String toString() { 66 | StringBuilder sb = new StringBuilder(); 67 | sb.append('['); 68 | for (int i = 0; i < count; i++) { 69 | if (i != 0) sb.append(", "); 70 | sb.append(keys[i]).append(':').append(values[i]); 71 | } 72 | sb.append(']'); 73 | return sb.toString(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/kilim/http/Utils.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.http; 8 | 9 | import java.lang.reflect.Array; 10 | 11 | public class Utils { 12 | public static Object[] growArray(Object[] input, int extraRoom) { 13 | int size = input.length + extraRoom; 14 | Object[] ret = (Object[]) Array.newInstance(input.getClass().getComponentType(), size); 15 | System.arraycopy(input,0,ret,0,input.length); 16 | return ret; 17 | } 18 | 19 | public static int[] growArray(int[] input, int extraRoom) { 20 | int size = input.length + extraRoom; 21 | int[] ret = (int[]) Array.newInstance(input.getClass().getComponentType(), size); 22 | System.arraycopy(input,0,ret,0,input.length); 23 | return ret; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/kilim/mirrors/ClassMirrorNotFoundException.java: -------------------------------------------------------------------------------- 1 | // Copyright 2010 by sriram - offered under the terms of the MIT License 2 | 3 | package kilim.mirrors; 4 | 5 | public class ClassMirrorNotFoundException extends Exception { 6 | 7 | /** 8 | * 9 | */ 10 | private static final long serialVersionUID = 5147833200948234264L; 11 | 12 | public ClassMirrorNotFoundException (String msg) { 13 | super(msg); 14 | } 15 | public ClassMirrorNotFoundException(Throwable cause) { 16 | super(cause); 17 | } 18 | public ClassMirrorNotFoundException(String className, 19 | ClassNotFoundException e) { 20 | super(className, e); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/kilim/nio/ExposedBais.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | package kilim.nio; 7 | 8 | import java.io.ByteArrayInputStream; 9 | 10 | /** 11 | * A hack that exposes the bytearray inside the ByteArrayInputStream. This is to 12 | * avoid copying the byte array when toByteArray() is called 13 | */ 14 | public class ExposedBais extends ByteArrayInputStream { 15 | 16 | public ExposedBais(int size) { 17 | super(new byte[size]); 18 | } 19 | 20 | public ExposedBais(byte[] buf, int offset, int length) { 21 | super(buf, offset, length); 22 | } 23 | 24 | public ExposedBais(byte[] buf) { 25 | super(buf); 26 | } 27 | 28 | public byte[] toByteArray() { 29 | return super.buf; 30 | } 31 | 32 | public void setCount(int n) { 33 | super.count = n; 34 | } 35 | } -------------------------------------------------------------------------------- /src/kilim/nio/ExposedBaos.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.nio; 8 | 9 | import java.io.ByteArrayOutputStream; 10 | import java.nio.ByteBuffer; 11 | 12 | /** 13 | * A hack that exposes the bytearray inside the ByteArrayOutputStream. This is to 14 | * avoid copying the byte array when toByteArray() is called. 15 | */ 16 | 17 | public class ExposedBaos extends ByteArrayOutputStream { 18 | public ExposedBaos() { 19 | super(); 20 | } 21 | 22 | public ExposedBaos(int size) { 23 | super(size); 24 | } 25 | 26 | @Override 27 | public byte[] toByteArray() { 28 | return buf; 29 | } 30 | 31 | public ByteBuffer toByteBuffer() { 32 | return ByteBuffer.wrap(buf, 0, count); 33 | } 34 | 35 | public void setCount(int n) { 36 | super.count = n; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/kilim/nio/SessionTask.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.nio; 8 | 9 | import java.io.IOException; 10 | import kilim.Task; 11 | 12 | public class SessionTask extends Task { 13 | public EndPoint endpoint; 14 | 15 | public void close() { 16 | if (endpoint != null) { 17 | IOException ex = endpoint.close2(); 18 | if (ex != null) Sched.log(getScheduler(),this,ex); 19 | } 20 | } 21 | private static class Sched extends kilim.AffineScheduler { 22 | static void log(kilim.Scheduler sched,Object src,Object obj) { logRelay(sched,src,obj); } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/kilim/nio/SockEvent.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.nio; 8 | 9 | import java.nio.channels.spi.AbstractSelectableChannel; 10 | 11 | import kilim.Mailbox; 12 | 13 | public class SockEvent { 14 | public SockEvent(Mailbox aReplyTo, AbstractSelectableChannel ach, int ops) { 15 | ch = ach; 16 | interestOps = ops; 17 | replyTo = aReplyTo; 18 | } 19 | 20 | public int interestOps; // SelectionKey.OP_* .. 21 | public AbstractSelectableChannel ch; 22 | public Mailbox replyTo; 23 | } 24 | -------------------------------------------------------------------------------- /src/kilim/support/JettyHandler.java: -------------------------------------------------------------------------------- 1 | package kilim.support; 2 | 3 | import java.io.IOException; 4 | import javax.servlet.AsyncContext; 5 | import javax.servlet.ServletException; 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | import kilim.Fiber; 9 | import kilim.Pausable; 10 | import org.eclipse.jetty.server.Request; 11 | import org.eclipse.jetty.server.handler.AbstractHandler; 12 | 13 | 14 | 15 | public class JettyHandler extends AbstractHandler { 16 | Iface handler; 17 | public JettyHandler(Iface handler) { this.handler = handler; } 18 | 19 | public void handle(final String target,final Request br,final HttpServletRequest req,final HttpServletResponse resp) throws IOException, ServletException { 20 | final AsyncContext async = req.startAsync(); 21 | new kilim.Task() { 22 | public void execute() throws Pausable, Exception { 23 | try { 24 | String result = handler.handle(target,br,req,resp); 25 | if (result != null) resp.getOutputStream().print(result); 26 | } 27 | catch (Exception ex) { resp.sendError(500,"the server encountered an error"); } 28 | br.setHandled(true); 29 | async.complete(); 30 | } 31 | }.start(); 32 | } 33 | 34 | 35 | public interface Iface { 36 | String handle(String target,Request br,HttpServletRequest req,HttpServletResponse resp) throws Pausable, Exception; 37 | } 38 | 39 | /** 40 | * java 7 doesn't support default interface methods so we need a dummy impl of the woven handler 41 | * this needs to be in a superclass, otherwise kilim will refuse to weave the real handle method 42 | */ 43 | public static abstract class Java7Handler implements Iface { 44 | public String handle(String arg0, 45 | Request arg1,HttpServletRequest arg2,HttpServletResponse arg3, 46 | Fiber arg4) 47 | throws Pausable,Exception { 48 | return null; 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/kilim/timerservice/Timer.java: -------------------------------------------------------------------------------- 1 | // Copyright 2014 nilangshah - offered under the terms of the MIT License 2 | 3 | package kilim.timerservice; 4 | 5 | 6 | import kilim.Event; 7 | import kilim.EventSubscriber; 8 | import kilim.concurrent.VolatileBoolean; 9 | 10 | public class Timer implements Comparable { 11 | private volatile long nextExecutionTime; 12 | public VolatileBoolean onQueue = new VolatileBoolean(false); //true if timer is already on timerqueue 13 | public volatile boolean onHeap = false; //true if timer is already on timerHeap 14 | 15 | public static final int TIMED_OUT = 3; 16 | public static final Event timedOut = new Event(TIMED_OUT); 17 | 18 | 19 | public int index; 20 | 21 | public EventSubscriber es; 22 | 23 | public Timer(EventSubscriber es) { 24 | this.es = es; 25 | } 26 | 27 | @Override 28 | public int compareTo(Timer o) { 29 | return (int) (((Long) nextExecutionTime)) 30 | .compareTo((Long) o.nextExecutionTime); 31 | } 32 | 33 | // -2: deferred (timer has completed) 34 | // -1: cancelled 35 | // 0: move to heap before processing 36 | // : process on queue if ready, otherwise move to heap 37 | /** set the timer relative to the current time, ie set a delay (in milliseconds) */ 38 | public void setTimer(long timeoutMillis) { 39 | nextExecutionTime = System.currentTimeMillis() + timeoutMillis; 40 | } 41 | /** set the timer value explicitly, ie not relative to the current time */ 42 | public void setLiteral(long value) { 43 | nextExecutionTime = value; 44 | } 45 | 46 | public void cancel(){ 47 | nextExecutionTime = -1; 48 | } 49 | 50 | public long getExecutionTime(){ 51 | return nextExecutionTime; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/kilim/timerservice/TimerPriorityHeap.java: -------------------------------------------------------------------------------- 1 | // Copyright 2014 nilangshah - offered under the terms of the MIT License 2 | 3 | package kilim.timerservice; 4 | 5 | import java.util.Arrays; 6 | 7 | public class TimerPriorityHeap { 8 | private Timer[] queue; 9 | private int size = 0; 10 | 11 | public TimerPriorityHeap() { 12 | this(128); 13 | } 14 | 15 | public TimerPriorityHeap(int size) { 16 | queue = new Timer[size]; 17 | } 18 | 19 | public int size() { 20 | return size; 21 | } 22 | 23 | public Timer peek() { 24 | return queue[1]; 25 | } 26 | 27 | public boolean isEmpty() { 28 | return size == 0; 29 | } 30 | 31 | public void add(Timer task) { 32 | 33 | if (size + 1 == queue.length) 34 | queue = Arrays.copyOf(queue, 2 * queue.length); 35 | queue[++size] = task; 36 | heapifyUp(size); 37 | 38 | } 39 | 40 | public void reschedule(int i) { 41 | heapifyUp(i); 42 | heapifyDown(i); 43 | 44 | } 45 | 46 | private void heapifyUp(int k) { 47 | while (k > 1) { 48 | int j = k >> 1; 49 | if (queue[j].getExecutionTime() <= queue[k].getExecutionTime()) 50 | break; 51 | Timer tmp = queue[j]; 52 | queue[j] = queue[k]; 53 | queue[j].index = j; 54 | queue[k] = tmp; 55 | queue[k].index = k; 56 | k = j; 57 | } 58 | } 59 | 60 | private void heapifyDown(int k) { 61 | int j; 62 | while ((j = k << 1) <= size && j > 0) { 63 | if (j < size 64 | && queue[j].getExecutionTime() > queue[j + 1] 65 | .getExecutionTime()) 66 | j++; 67 | if (queue[k].getExecutionTime() <= queue[j].getExecutionTime()) 68 | break; 69 | Timer tmp = queue[j]; 70 | queue[j] = queue[k]; 71 | queue[j].index = j; 72 | queue[k] = tmp; 73 | queue[k].index = k; 74 | k = j; 75 | } 76 | } 77 | 78 | public void poll() { 79 | queue[1] = queue[size]; 80 | queue[1].index = 1; 81 | queue[size--] = null; 82 | heapifyDown(1); 83 | 84 | } 85 | 86 | // private void heapify() { 87 | // for (int i = size / 2; i >= 1; i--) 88 | // heapifyDown(i); 89 | // } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /src/kilim/tools/Agent.java: -------------------------------------------------------------------------------- 1 | package kilim.tools; 2 | 3 | 4 | import java.lang.instrument.ClassFileTransformer; 5 | import java.lang.instrument.IllegalClassFormatException; 6 | import java.lang.instrument.Instrumentation; 7 | import java.security.ProtectionDomain; 8 | import java.util.TreeMap; 9 | import kilim.WeavingClassLoader; 10 | 11 | public class Agent implements ClassFileTransformer { 12 | public static TreeMap map; 13 | 14 | public byte[] transform( 15 | ClassLoader loader, 16 | String name, 17 | Class klass, 18 | ProtectionDomain protectionDomain, 19 | byte[] bytes) 20 | throws IllegalClassFormatException { 21 | 22 | 23 | String memory = "com.sun.tools.javac.launcher.Main$MemoryClassLoader"; 24 | if (loader != null && memory.equals(loader.getClass().getName())) { 25 | String cname = WeavingClassLoader.makeResourceName(name); 26 | map.put(cname,bytes); 27 | } 28 | return bytes; 29 | } 30 | 31 | public static void premain(String agentArgs,Instrumentation inst) { 32 | if (map==null) map = new TreeMap(); 33 | inst.addTransformer(new Agent()); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/kilim/tools/P.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.tools; 8 | 9 | // Various print routines to call from jvml files (*.j). More convenient 10 | // than calling System.out.println. 11 | 12 | public class P { 13 | // Call as invokestatic kilim/tools/P/pi(I)V 14 | public static void pi(int i) { 15 | System.out.println(i); 16 | } 17 | 18 | // Call as invokestatic kilim/tools/P/pn()V 19 | public static void pn() { 20 | System.out.println(); 21 | } 22 | 23 | // Call as invokestatic kilim/tools/P/pn(Ljava/lang/Object;)V 24 | public static void pn(Object o) { 25 | System.out.println(o); 26 | } 27 | 28 | // Call as invokestatic kilim/tools/P/p(Ljava/lang/Object;)V 29 | public static void p(Object o) { 30 | System.out.print(o); 31 | } 32 | 33 | // Call as invokestatic kilim/tools/P/ps(Ljava/lang/Object;)V 34 | public static void ps(Object o) { 35 | System.out.print(o); 36 | System.out.print(" "); 37 | } 38 | // Call as invokestatic kilim/tools/P/ptest()V 39 | public static void ptest() { 40 | System.out.println("test"); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /test/kilim/test/AllNotWoven.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.test; 8 | 9 | import junit.framework.Test; 10 | import junit.framework.TestSuite; 11 | 12 | public class AllNotWoven extends TestSuite { 13 | public static Test suite() { 14 | TestSuite ret = new AllNotWoven(); 15 | ret.addTestSuite(TestTypeDesc.class); 16 | ret.addTestSuite(TestUsage.class); 17 | ret.addTestSuite(TestValue.class); 18 | ret.addTestSuite(TestFrame.class); 19 | ret.addTestSuite(TestBasicBlock.class); 20 | ret.addTestSuite(TestJSR.class); 21 | ret.addTestSuite(TestFlow.class); 22 | ret.addTestSuite(TestExprs.class); 23 | ret.addTestSuite(TestClassInfo.class); 24 | ret.addTestSuite(TestInvalidPausables.class); 25 | ret.addTestSuite(TestDynamicWeaver.class); 26 | return ret; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /test/kilim/test/AllWoven.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.test; 8 | 9 | import junit.framework.Test; 10 | import junit.framework.TestSuite; 11 | 12 | public class AllWoven extends TestSuite { 13 | private static Class lambdaClass; 14 | private static boolean java8; 15 | static { 16 | try { 17 | lambdaClass = AllWoven.class.getClassLoader().loadClass("kilim.test.TestLambda"); 18 | java8 = true; 19 | } 20 | catch (ClassNotFoundException ex) {} 21 | } 22 | 23 | public static Test suite() { 24 | TestSuite ret = new AllWoven(); 25 | ret.addTestSuite(TestPrefThread.class); 26 | ret.addTestSuite(TestYield.class); 27 | ret.addTestSuite(TestInterface.class); 28 | ret.addTestSuite(TestAbstractExtends.class); 29 | if (java8) 30 | ret.addTestSuite(lambdaClass); 31 | ret.addTestSuite(TestYieldExceptions.class); 32 | ret.addTestSuite(TestYieldJSR.class); 33 | ret.addTestSuite(TestMailbox.class); 34 | ret.addTestSuite(TestLock.class); 35 | ret.addTestSuite(TestGenerics.class); 36 | ret.addTestSuite(TestIO.class); 37 | ret.addTestSuite(TestHTTP.class); 38 | return ret; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /test/kilim/test/TaskTestClassLoader.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.test; 8 | 9 | import java.io.File; 10 | import java.io.FileInputStream; 11 | import java.io.IOException; 12 | import java.net.URL; 13 | 14 | public class TaskTestClassLoader extends ClassLoader { 15 | static String wclassDir; 16 | 17 | static { 18 | URL baseURL = Thread.currentThread().getContextClassLoader().getResource("kilim/test/TaskTestClassLoader.class"); 19 | String path = baseURL.getPath(); 20 | wclassDir = path.substring(0, path.indexOf("/classes/")) + "/wclasses/"; 21 | } 22 | 23 | public TaskTestClassLoader(ClassLoader aParent) { 24 | super(aParent); 25 | } 26 | 27 | @Override 28 | public Class loadClass(String className, boolean resolve) 29 | throws ClassNotFoundException { 30 | Class ret = findLoadedClass(className); 31 | if (ret == null && className.startsWith("kilim")) { 32 | File f = new File(wclassDir + className.replace('.', '/') + ".class"); 33 | if (f.exists()) { 34 | try { 35 | byte[] bytes = getBytes(f); 36 | // if (resolve) { 37 | ret = defineClass(className, bytes, 0, bytes.length); 38 | // } 39 | } catch (IOException ioe) { 40 | System.err.println("Error loading class " + className + " from file " + f.getPath()); 41 | ioe.printStackTrace(); 42 | // Not supposed to happen 43 | System.exit(1); 44 | } 45 | } 46 | } 47 | if (ret == null) { 48 | return resolve ? findSystemClass(className) 49 | : getParent().loadClass(className); 50 | } else { 51 | return ret; 52 | } 53 | } 54 | 55 | private byte[] getBytes(File f) throws IOException { 56 | int size = (int)f.length(); 57 | byte[] bytes = new byte[size]; 58 | int remaining = size; 59 | int i = 0; 60 | FileInputStream fis = new FileInputStream(f); 61 | while (remaining > 0) { 62 | int n = fis.read(bytes, i, remaining); 63 | if (n == -1) break; 64 | remaining -= n; 65 | i += n; 66 | } 67 | return bytes; 68 | } 69 | 70 | public static void main(String[] args) throws Exception { 71 | Class c = new TaskTestClassLoader(Thread.currentThread().getContextClassLoader()).loadClass(args[0], true); 72 | c.newInstance(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /test/kilim/test/TestAbstractExtends.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.test; 8 | 9 | import junit.framework.TestCase; 10 | import kilim.Pausable; 11 | import kilim.Task; 12 | 13 | /** 14 | * 15 | * 16 | */ 17 | public class TestAbstractExtends extends TestCase { 18 | static String msg = "aaaaaa"; 19 | 20 | public static interface Service { 21 | public void service(String message) throws Pausable; 22 | } 23 | 24 | public static abstract class StandardService implements Service { 25 | 26 | @Override 27 | public void service(String message) throws Pausable { 28 | doService(message); 29 | } 30 | 31 | public abstract void doService(String message) throws Pausable; 32 | 33 | } 34 | 35 | public static class MyService extends StandardService { 36 | 37 | @Override 38 | public void doService(String message) throws Pausable { 39 | if (message != msg) 40 | fail("mismatch between expected and received messages"); 41 | } 42 | } 43 | 44 | public void testRun() { 45 | Task task = new Task() { 46 | public void execute() throws kilim.Pausable ,Exception { 47 | Service service = new MyService(); 48 | service.service(msg); 49 | }; 50 | }; 51 | 52 | task.start(); 53 | task.joinb(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /test/kilim/test/TestBasicBlock.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.test; 8 | 9 | import kilim.analysis.MethodFlow; 10 | 11 | public class TestBasicBlock extends Base { 12 | 13 | @Override 14 | protected void setUp() throws Exception { 15 | cache("kilim.test.ex.ExBasicBlock"); 16 | } 17 | 18 | public void testNumFlows() { 19 | assertEquals(getFlows().size(), 8); 20 | } 21 | 22 | private void checkSize(String methodName, int expectedSize) { 23 | MethodFlow f = getFlow(methodName); 24 | if (f == null) 25 | return; 26 | if (f.getBasicBlocks().size() != expectedSize) { 27 | fail("Method " + methodName + ": expected flow size = " 28 | + expectedSize + ", instead got " 29 | + f.getBasicBlocks().size()); 30 | } 31 | } 32 | 33 | public void testNoopSize() { 34 | checkSize("noop", 1); 35 | } 36 | 37 | public void testLoopSize() { 38 | checkSize("loop", 4); 39 | } 40 | 41 | public void testExceptionSize() { 42 | checkSize("exception", 8); 43 | } 44 | 45 | public void testNestedSize() { 46 | checkSize("nestedloop", 6); 47 | } 48 | 49 | public void testComplexSize() { 50 | checkSize("complex", 14); 51 | } 52 | 53 | public void testNoopCov() { 54 | checkCov("noop"); 55 | } 56 | 57 | public void testLoopCov() { 58 | checkCov("loop"); 59 | } 60 | 61 | public void testExceptionCov() { 62 | checkCov("exception"); 63 | } 64 | 65 | public void testNestedCov() { 66 | checkCov("nestedloop"); 67 | } 68 | 69 | public void testComplexCov() { 70 | checkCov("complex"); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /test/kilim/test/TestClassInfo.java: -------------------------------------------------------------------------------- 1 | package kilim.test; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | 6 | import junit.framework.TestCase; 7 | import kilim.analysis.ClassInfo; 8 | 9 | public class TestClassInfo extends TestCase { 10 | public void testContains() throws Exception { 11 | List classInfoList = new LinkedList(); 12 | 13 | ClassInfo classOne = new ClassInfo("kilim/S_01.class", "whocares".getBytes("UTF-8")); 14 | classInfoList.add(classOne); 15 | 16 | ClassInfo classTwo = new ClassInfo("kilim/S_01.class", "whocares".getBytes("UTF-8")); 17 | assertTrue(classInfoList.contains(classTwo)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/kilim/test/TestExprs.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.test; 8 | 9 | 10 | /** 11 | * An attempt to exercise all the bytecode associated with primitive 12 | * types (loading/storing from registers, array operations, arithmetic operations etc.) 13 | */ 14 | public class TestExprs extends Base { 15 | public void testInts() throws Exception { 16 | cache("kilim.test.ex.ExInts"); 17 | } 18 | public void testLongs() throws Exception { 19 | cache("kilim.test.ex.ExLongs"); 20 | } 21 | 22 | public void testFloats() throws Exception { 23 | cache("kilim.test.ex.ExFloats"); 24 | } 25 | 26 | public void testDoubles() throws Exception { 27 | cache("kilim.test.ex.ExDoubles"); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/kilim/test/TestFlow.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.test; 8 | 9 | import static kilim.Constants.D_BYTE; 10 | import kilim.analysis.BasicBlock; 11 | import kilim.analysis.Frame; 12 | import kilim.analysis.IncompatibleTypesException; 13 | import kilim.analysis.MethodFlow; 14 | import kilim.analysis.TypeDesc; 15 | import kilim.analysis.Value; 16 | import static kilim.test.TestTypeDesc.mergeType; 17 | 18 | public class TestFlow extends Base { 19 | 20 | @Override 21 | protected void setUp() throws Exception { 22 | cache("kilim.test.ex.ExFlow"); 23 | } 24 | 25 | public void testMerge() throws IncompatibleTypesException { 26 | MethodFlow flow = getFlow("loop"); 27 | if (flow == null) 28 | return; 29 | // Make sure the merging is fine. There used to be a bug 30 | assertEquals("Lkilim/test/ex/ExA;", mergeType("Lkilim/test/ex/ExC;", "Lkilim/test/ex/ExD;")); 31 | assertEquals("Lkilim/test/ex/ExA;", mergeType("Lkilim/test/ex/ExD;", "Lkilim/test/ex/ExC;")); 32 | BasicBlock bb = getBBForMethod(flow, "join"); 33 | assertTrue(bb != null); 34 | Frame f = bb.startFrame; 35 | // Check Locals 36 | // assertEquals("Lkilim/test/ex/ExFlow;", f.getLocal(0)); 37 | assertEquals("Lkilim/test/ex/ExA;", f.getLocal(1).getTypeDesc()); 38 | // assertSame(D_INT, f.getLocal(2)); 39 | // Check operand stack 40 | assertSame(D_BYTE, f.getStack(0).getTypeDesc()); 41 | assertEquals("Lkilim/test/ex/ExFlow;", f.getStack(1).getTypeDesc()); 42 | assertEquals("Lkilim/test/ex/ExA;", f.getStack(2).getTypeDesc()); 43 | } 44 | 45 | public void testConstants() throws IncompatibleTypesException { 46 | MethodFlow flow = getFlow("loop"); 47 | if (flow == null) 48 | return; 49 | BasicBlock bb = getBBForMethod(flow, "join"); 50 | Frame f = bb.startFrame; 51 | assertSame(f.getLocal(2).getConstVal(), Value.NO_VAL); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /test/kilim/test/TestGenerics.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.test; 8 | 9 | import junit.framework.TestCase; 10 | import kilim.ExitMsg; 11 | import kilim.Mailbox; 12 | import kilim.Scheduler; 13 | import kilim.Task; 14 | import kilim.test.ex.ExYieldBase; 15 | 16 | public class TestGenerics extends TestCase { 17 | 18 | public void testGenerics() throws Exception { 19 | ExYieldBase task; 20 | 21 | task = (ExYieldBase) (Class.forName("kilim.test.ex.ExGenerics").newInstance()); 22 | runTask(task); 23 | } 24 | 25 | public static void runTask(Task task) throws Exception { 26 | Mailbox exitmb = new Mailbox(); 27 | Scheduler s = Scheduler.make(1); 28 | task.informOnExit(exitmb); 29 | task.setScheduler(s); 30 | task.start(); 31 | 32 | ExitMsg m = exitmb.getb(); 33 | if (m == null) { 34 | fail("Timed Out"); 35 | } else { 36 | Object res = m.result; 37 | if (res instanceof Throwable) { 38 | ((Throwable)res).printStackTrace(); 39 | fail(m.toString()); 40 | } 41 | } 42 | s.shutdown(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /test/kilim/test/TestInvalidPausables.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.test; 8 | 9 | import junit.framework.TestCase; 10 | import kilim.KilimException; 11 | import kilim.WeavingClassLoader; 12 | 13 | public class TestInvalidPausables extends TestCase { 14 | private static boolean debug = false; 15 | private void ensureException(String className) { 16 | try { 17 | new WeavingClassLoader().weaveClass(className); 18 | fail("Expected weave exception while processing " + className); 19 | } catch (KilimException ke) { 20 | if (debug) System.out.println(ke); 21 | } catch (Exception e) { 22 | fail(e.toString()); 23 | } 24 | } 25 | public void testWeaveConstructor() { 26 | ensureException("kilim.test.ex.ExInvalidConstructor"); 27 | ensureException("kilim.test.ex.ExInvalidConstructor2"); 28 | ensureException("kilim.test.ex.ExInvalidConstructor3"); 29 | } 30 | public void testWeaveSynchronized() { 31 | ensureException("kilim.test.ex.ExInvalidSynchronized"); 32 | ensureException("kilim.test.ex.ExInvalidSynchronized1"); 33 | } 34 | public void testWeaveStatic() { 35 | ensureException("kilim.test.ex.ExInvalidStaticBlock"); 36 | } 37 | 38 | public void testWeaveMethod() { 39 | ensureException("kilim.test.ex.ExInvalidCallP_NP"); 40 | } 41 | 42 | public void testWeaveSuperPausable() { 43 | ensureException("kilim.test.ex.ExInvalidNPDerived"); 44 | 45 | } 46 | 47 | public void testWeaveSuperNotPausable() { 48 | ensureException("kilim.test.ex.ExInvalidPDerived"); 49 | } 50 | 51 | public void testWeaveInterfacePausable() { 52 | ensureException("kilim.test.ex.ExInvalidPImp"); 53 | ensureException("kilim.test.ex.ExInvalidPFace"); 54 | } 55 | 56 | public void testWeaveInterfaceNotPausable() { 57 | ensureException("kilim.test.ex.ExInvalidNPImp"); 58 | ensureException("kilim.test.ex.ExInvalidNPFace"); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /test/kilim/test/TestJSR.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.test; 8 | 9 | import java.util.ArrayList; 10 | 11 | import kilim.analysis.BasicBlock; 12 | import kilim.analysis.MethodFlow; 13 | 14 | public class TestJSR extends Base { 15 | public void testJSRSizes() throws Exception { 16 | String className = "kilim.test.ex.ExJSR"; 17 | try { 18 | Class.forName(className); 19 | } catch (ClassNotFoundException cnfe) { 20 | fail("Please use jasmin to compile " + className); 21 | } catch (VerifyError e) { 22 | fail("Verification error for " + className + ": " + e.getMessage()); 23 | } 24 | cache(className); 25 | MethodFlow flow = getFlow("simpleJSR"); 26 | assertEquals(3, flow.getBasicBlocks().size()); 27 | flow = getFlow("pausableJSR1"); 28 | // System.out.println(flow.getBasicBlocks()); 29 | assertEquals(5, flow.getBasicBlocks().size()); 30 | 31 | flow = getFlow("pausableJSR2"); 32 | ArrayList bbs = flow.getBasicBlocks(); 33 | assertEquals(9, bbs.size()); 34 | 35 | // make sure the blocks are unique 36 | int flag = 1 << 12; 37 | for (BasicBlock bb: bbs) { 38 | assertFalse("BasicBlock list contains duplicates", bb.hasFlag(flag)); 39 | bb.setFlag(flag); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /test/kilim/test/TestLock.java: -------------------------------------------------------------------------------- 1 | package kilim.test; 2 | 3 | import junit.framework.TestCase; 4 | import kilim.ExitMsg; 5 | import kilim.ForkJoinScheduler; 6 | import kilim.Mailbox; 7 | import kilim.Pausable; 8 | import kilim.ReentrantLock; 9 | import kilim.Scheduler; 10 | import kilim.Task; 11 | 12 | public class TestLock extends TestCase{ 13 | static int numThreads = 4; 14 | static int maxDelay = 30; 15 | static int numTasks = 20; 16 | static int numIters = 20; 17 | static boolean force = false; 18 | static boolean preLock = true; 19 | static int ratio = 10; 20 | static int timeout = maxDelay/ratio*numIters*numTasks/numThreads + maxDelay*numIters; 21 | 22 | public void testLocks() { 23 | Scheduler scheduler = force ? new ForkJoinScheduler(numThreads) : Scheduler.getDefaultScheduler(); 24 | Mailbox mb = new Mailbox(); 25 | for (int i = 0; i < numTasks; i++) { 26 | Task t = new LockTask(); 27 | t.informOnExit(mb); 28 | t.setScheduler(scheduler); 29 | t.start(); 30 | } 31 | boolean ok = true; 32 | for (int i = 0; i < numTasks; i++) { 33 | ExitMsg em = mb.getb(timeout); 34 | assertNotNull("Timed out. #tasks finished = " + i + " of " + numTasks, em); 35 | if (em.result instanceof Exception) { 36 | ok = false; break; 37 | } 38 | } 39 | scheduler.shutdown(); 40 | assertTrue(ok); 41 | } 42 | 43 | static void sleep(int delay) { 44 | try { Thread.sleep(delay); } 45 | catch (InterruptedException ex) {} 46 | } 47 | 48 | static int delay() { 49 | return (int) (maxDelay*Math.random()); 50 | } 51 | 52 | static class LockTask extends Task { 53 | ReentrantLock syncLock = new ReentrantLock(); 54 | @Override 55 | public void execute() throws Pausable, Exception { 56 | Task.sleep(delay()); 57 | if (preLock) syncLock.preLock(); 58 | try { 59 | for (int i = 0; i < numIters; i++) { 60 | syncLock.lock(); 61 | Task.sleep(delay()); 62 | syncLock.unlock(); 63 | TestLock.sleep(delay()/ratio); 64 | } 65 | } catch (Exception e) { 66 | e.printStackTrace(); 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /test/kilim/test/TestPrefThread.java: -------------------------------------------------------------------------------- 1 | package kilim.test; 2 | 3 | import junit.framework.TestCase; 4 | import kilim.ExitMsg; 5 | import kilim.Mailbox; 6 | import kilim.Pausable; 7 | import kilim.Scheduler; 8 | import kilim.Task; 9 | 10 | public class TestPrefThread extends TestCase { 11 | 12 | public void testPreferredThread() throws Exception { 13 | int NUM_TASKS = 5 * 1000; 14 | Scheduler s = Scheduler.make(10); 15 | Mailbox exitMB = new Mailbox(); 16 | Task t[] = new Task[NUM_TASKS]; 17 | for (int i = 0; i < NUM_TASKS; i++) { 18 | t[i] = new PinnedTask(i); 19 | t[i].setScheduler(s); 20 | t[i].informOnExit(exitMB); 21 | t[i].start(); 22 | } 23 | int i = 0; 24 | while (i != NUM_TASKS) { 25 | t[i].isDone(); 26 | i++; 27 | } 28 | s.shutdown(); 29 | 30 | } 31 | 32 | static class PinnedTask extends Task { 33 | private int taskId; 34 | private long prefId; 35 | 36 | public PinnedTask(int taskId) { 37 | this.taskId = taskId; 38 | } 39 | 40 | @Override 41 | public void execute() throws Pausable, Exception { 42 | prefId = Thread.currentThread().getId(); 43 | this.pinToThread(); 44 | for (int i = 0; i < 10000; i++) { 45 | Task.yield(); 46 | long threadId = Thread.currentThread().getId(); 47 | 48 | if (prefId != threadId) { 49 | System.out.println("Task " + taskId 50 | + "not resumed on preferred thread " + prefId 51 | + "but on thread" + threadId); 52 | Task.exit(1); 53 | } 54 | } 55 | Task.exit(0); 56 | 57 | } 58 | 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /test/kilim/test/TestRing.java: -------------------------------------------------------------------------------- 1 | package kilim.test; 2 | 3 | import junit.framework.TestCase; 4 | 5 | import java.util.Random; 6 | 7 | import kilim.RingQueue; 8 | 9 | public class TestRing extends TestCase { 10 | public void testInfiniteQueue() { 11 | Integer[] a = mkRandom(); 12 | RingQueue rq = new RingQueue(10); 13 | for (int i = 0; i < a.length; i++) { 14 | assertTrue("put returned false", rq.put(a[i])); 15 | } 16 | assertEquals("Queue size", a.length, rq.size()); 17 | for (int i = 0; i < a.length; i++) { 18 | assertEquals("get[" + i + " ]returned different element", a[i], rq.get()); 19 | } 20 | // No more elements. The next ha d better be null 21 | assertNull("Queue should not have any more elements", rq.get()); 22 | assertTrue(rq.size() == 0); 23 | } 24 | 25 | public void testBoundedQueue() { 26 | Integer[] a = mkRandom(); 27 | RingQueue rq = new RingQueue(10, a.length); 28 | for (int i = 0; i < a.length; i++) { 29 | assertTrue("put returned false", rq.put(a[i])); 30 | } 31 | assertFalse("put should not accept more than bound", rq.put(100)); 32 | assertTrue(rq.size() == a.length); 33 | for (int i = 0; i < a.length; i++) { 34 | assertEquals("get[" + i + " ]returned different element", a[i], rq.get()); 35 | } 36 | // No more elements. The next had better be null 37 | assertNull("Queue should not have any more elements", rq.get()); 38 | assertTrue(rq.size() == 0); 39 | } 40 | 41 | private Integer[] mkRandom() { 42 | Random r = new Random(); 43 | Integer[] ret = new Integer[1000]; 44 | for (int i = 0; i < 1000; i++) { 45 | ret[i] = new Integer(r.nextInt(1000)); 46 | } 47 | return ret; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /test/kilim/test/TestUsage.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.test; 8 | 9 | import java.util.ArrayList; 10 | 11 | import kilim.analysis.Usage; 12 | import junit.framework.TestCase; 13 | 14 | public class TestUsage extends TestCase { 15 | /** 16 | * Tests whether a bunch of reads and writes produces the appropriate live-in 17 | */ 18 | public void testReadWrite() { 19 | Usage u = new Usage(4); 20 | u.read(1); 21 | u.read(2); 22 | u.write(2); 23 | u.write(3); 24 | u.evalLiveIn(new ArrayList(),null); 25 | assertFalse(u.isLiveIn(0)); 26 | assertTrue(u.isLiveIn(1)); 27 | assertTrue(u.isLiveIn(2)); 28 | assertFalse(u.isLiveIn(3)); 29 | } 30 | 31 | public void testChange() { 32 | Usage u = new Usage(31); 33 | Usage ufollow1 = new Usage(31); 34 | Usage ufollow2 = new Usage(31); 35 | // 29:R 36 | // 30:W 37 | // Usage 1 and 2. 38 | // 28:in 28:not_in 39 | // 29:in 29:not_in 40 | // 30:in 30:in 41 | // Expected usage.in : 28:in 29:in 30:not_in 42 | u.read(29); u.write(30); 43 | for (int ii=0; ii < 31; ii++) u.setBornIn(ii); 44 | ufollow1.setLiveIn(28); ufollow1.setLiveIn(29); ufollow1.setLiveIn(30); 45 | ufollow2.setLiveIn(30); 46 | ArrayList ua = new ArrayList(2); 47 | ua.add(ufollow1); ua.add(ufollow2); 48 | assertTrue(u.evalLiveIn(ua,null)); // should return changed == true 49 | for (int i = 0; i < 28; i++) { 50 | assertFalse(u.isLiveIn(i)); 51 | } 52 | assertTrue(u.isLiveIn(28)); 53 | assertTrue(u.isLiveIn(29)); 54 | assertFalse(u.isLiveIn(30)); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /test/kilim/test/TestValue.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.test; 8 | 9 | import kilim.analysis.Value; 10 | import junit.framework.TestCase; 11 | import static kilim.Constants.*; 12 | import kilim.analysis.KilimContext; 13 | 14 | public class TestValue extends TestCase { 15 | 16 | private static Value merge(Value self,Value other) { 17 | return self.merge(KilimContext.DEFAULT.detector,other); 18 | } 19 | 20 | 21 | public void testSameSiteMerge() { 22 | Value v = Value.make(10, D_STRING); 23 | v = merge(v,Value.make(20, D_OBJECT)); 24 | Value oldV = v; 25 | for (int i = 0; i < 10; i++) { 26 | v = merge(v,Value.make(10, D_STRING)); 27 | } 28 | assertSame(oldV, v); 29 | } 30 | 31 | public void testDifferentSitesMerge() { 32 | Value v1 = Value.make(2, D_INT); 33 | Value v2 = Value.make(3, D_INT); 34 | Value v3 = Value.make(5, D_INT); 35 | Value v = merge(v1,v2); 36 | v = merge(v,v3); 37 | assertTrue(v.getNumSites() == 3); 38 | int[] sites = v.getCreationSites(); 39 | int prod = 1; 40 | for (int i = 0; i < 3; i++) { 41 | prod *= sites[i]; 42 | } 43 | assertTrue(prod == 30); 44 | 45 | Value oldV = v; 46 | 47 | // Ensure order of merges don't matter 48 | v = merge(v3,v2); 49 | v = merge(v,v1); 50 | assertEquals(v, oldV); 51 | } 52 | 53 | 54 | public void testTypeMerge() { 55 | Value v1 = Value.make(2, "Lkilim/test/ex/ExC;"); 56 | Value v2 = Value.make(3, "Lkilim/test/ex/ExD;"); 57 | Value v3 = Value.make(5, "Lkilim/test/ex/ExA;"); 58 | 59 | Value v = merge(v1,v1); 60 | assertSame(v, v1); 61 | 62 | v = merge(v1,v2); 63 | assertEquals("Lkilim/test/ex/ExA;", v.getTypeDesc()); 64 | v = merge(v3,v2); 65 | assertEquals("Lkilim/test/ex/ExA;", v.getTypeDesc()); 66 | 67 | Value v4 = Value.make(7, D_INT);; 68 | v = merge(v3,v4); 69 | assertSame(D_UNDEFINED, v.getTypeDesc()); 70 | } 71 | 72 | public void testConstMerge() { 73 | Value v1 = Value.make(99, D_STRING, "String1"); 74 | Value v2 = Value.make(100, D_STRING, new String("String1")); // create a new String 75 | Value v= merge(v1,v2); 76 | assertTrue(v.getConstVal().equals("String1")); 77 | v = merge(v1,Value.make(101, D_STRING, "Some other string")); 78 | assertTrue(v.getConstVal().equals(Value.NO_VAL)); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /test/kilim/test/TestYieldExceptions.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.test; 8 | 9 | import junit.framework.TestCase; 10 | import kilim.test.ex.ExCatch; 11 | 12 | public class TestYieldExceptions extends TestCase { 13 | /* 14 | * exception thrown in a pausable method. The 15 | * catch handler does not make any pausable calls 16 | */ 17 | public void testOrdinaryCatch() throws Exception { 18 | TestYield.runTask(new kilim.test.ex.ExCatch(0)); 19 | } 20 | 21 | /* 22 | * pausable method throws an exception and the 23 | * catch handler makes a pausable call as well 24 | */ 25 | public void testPausableCatch() throws Exception { 26 | TestYield.runTask(new kilim.test.ex.ExCatch(1)); 27 | } 28 | 29 | /* 30 | * catch handler throws and catches another exception 31 | */ 32 | public void testNestedException() throws Exception { 33 | TestYield.runTask(new kilim.test.ex.ExCatch(2)); 34 | } 35 | 36 | /* 37 | * try/finally surrounds try/catch. lots of exceptions 38 | * and pauses all around 39 | */ 40 | public void testTryCatchFinally() throws Exception { 41 | TestYield.runTask(new kilim.test.ex.ExCatch(3)); 42 | } 43 | 44 | public void testTryThrow() throws Exception { 45 | for (int ii=0; ii < 16; ii++) 46 | TestYield.runTask(new kilim.test.ex.ExCatch.TryThrow(ii)); 47 | } 48 | 49 | public void testTryThrowVars() throws Exception { 50 | for (int ii=0; ii < 16; ii++) 51 | TestYield.runTask(new kilim.test.ex.ExCatch.TryThrowVars(ii)); 52 | } 53 | 54 | public void testPausableBlocksBeforeCatch() throws Exception { 55 | TestYield.runTask(new kilim.test.ex.ExCatch(4)); 56 | } 57 | 58 | public void testRestoreBeforeDefine() throws Exception { 59 | TestYield.runTask(new kilim.test.ex.ExCatch(5)); 60 | } 61 | public void testWhileCatch() throws Exception { 62 | TestYield.runTask(new kilim.test.ex.ExCatch(6)); 63 | } 64 | public void testRestoreArgument() throws Exception { 65 | TestYield.runTask(new kilim.test.ex.ExCatch(7)); 66 | } 67 | public void testCorrectException() throws Exception { 68 | TestYield.runTask(new kilim.test.ex.ExCatch(8)); 69 | } 70 | 71 | public void testPureCatch() throws Exception { 72 | TestYield.runPure(new kilim.test.ex.ExCatch.Pure()); 73 | } 74 | public void testPausableInvokeCatch() throws Exception { 75 | TestYield.runTask(new kilim.test.ex.ExCatch(9)); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /test/kilim/test/TestYieldJSR.java: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2006, Sriram Srinivasan 2 | * 3 | * You may distribute this software under the terms of the license 4 | * specified in the file "License" 5 | */ 6 | 7 | package kilim.test; 8 | 9 | import junit.framework.TestCase; 10 | 11 | public class TestYieldJSR extends TestCase { 12 | 13 | /* 14 | * Ordinary jsr call. No inlining should happen 15 | */ 16 | public void testNonPausableJSR() throws Exception { 17 | TestYield.runTask("kilim.test.ex.ExYieldSub", 0); 18 | } 19 | 20 | /* 21 | * Single jsr call to a subroutine that calls Task.sleep. 22 | */ 23 | public void testSinglePausableJSR() throws Exception { 24 | TestYield.runTask("kilim.test.ex.ExYieldSub", 1); 25 | } 26 | 27 | /* 28 | * jsr sub1, jsr sub2 , jsr sub1 in sequence. Tests inlining 29 | * (because sub1 is called twice), and tests whether stack 30 | * and locals are preserved. 31 | */ 32 | public void testMultiplePausableJSRs() throws Exception { 33 | TestYield.runTask("kilim.test.ex.ExYieldSub", 2); 34 | } 35 | 36 | /* jsr sub1, jsr sub2, jsr sub1, jsr sub2, where sub2 is pausable 37 | * and sub1 is not. Only calls to sub2 should be inlined. We have 38 | * no automated way of checking this, but the behavior can certainly 39 | * be tested. 40 | */ 41 | public void testMixedJSRs() throws Exception { 42 | TestYield.runTask("kilim.test.ex.ExYieldSub", 3); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /test/kilim/test/ex/ExA.java: -------------------------------------------------------------------------------- 1 | package kilim.test.ex; 2 | 3 | 4 | public class ExA { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /test/kilim/test/ex/ExB.java: -------------------------------------------------------------------------------- 1 | package kilim.test.ex; 2 | 3 | public class ExB extends ExA { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /test/kilim/test/ex/ExBasicBlock.java: -------------------------------------------------------------------------------- 1 | package kilim.test.ex; 2 | 3 | import kilim.Pausable; 4 | import kilim.Task; 5 | 6 | public class ExBasicBlock { 7 | void noop() throws ArrayIndexOutOfBoundsException { 8 | } 9 | 10 | static void pausable() throws Pausable { 11 | "afakflkaflakd".getBytes(); 12 | } 13 | 14 | static int testFiber(Object testArgs1, Object[] testArgs) throws Pausable { 15 | Task.getCurrentTask(); 16 | int a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0; 17 | for (int i = 0; i < g; i++) { 18 | g = a + b + c + d + e + f; 19 | } 20 | return g; 21 | } 22 | 23 | int loop() throws Pausable { 24 | int sum = 0; 25 | for (int i = 0; i < 10; i++) { 26 | sum++; 27 | } 28 | return sum; 29 | } 30 | 31 | void nestedloop() throws Pausable { 32 | for (int i = 0; i < 100; i++) { 33 | while (i > 10) { 34 | i--; 35 | } 36 | } 37 | } 38 | 39 | void exception() throws Pausable { 40 | try { 41 | try { 42 | pausable(); 43 | } catch (ArrayIndexOutOfBoundsException e) { 44 | try { 45 | e.printStackTrace(); 46 | } catch (Throwable t) { 47 | noop(); 48 | } 49 | } 50 | } finally { 51 | noop(); 52 | } 53 | } 54 | 55 | void complex() throws Pausable { 56 | double d = 10.0; 57 | Object o = new Object(); 58 | for (int i = 0; i < 100; i++) { 59 | try { 60 | if (d > 10.3 && d < 10.5) { 61 | d = 20.0; 62 | try { 63 | synchronized(o) { 64 | o.hashCode(); 65 | } 66 | } catch (RuntimeException re) { 67 | throw new Error(re.toString()); 68 | } 69 | } 70 | } finally { 71 | d = 100.0; 72 | } 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /test/kilim/test/ex/ExC.java: -------------------------------------------------------------------------------- 1 | package kilim.test.ex; 2 | 3 | public class ExC extends ExA { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /test/kilim/test/ex/ExD.java: -------------------------------------------------------------------------------- 1 | package kilim.test.ex; 2 | 3 | public class ExD extends ExB { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /test/kilim/test/ex/ExEx.java: -------------------------------------------------------------------------------- 1 | package kilim.test.ex; 2 | 3 | import kilim.Pausable; 4 | 5 | public class ExEx { 6 | void noop(int i) throws Pausable {} 7 | 8 | void f() throws Pausable { 9 | int i = 0; 10 | try { 11 | noop(i); 12 | } catch (Exception e) { 13 | noop(i); 14 | } 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/kilim/test/ex/ExException.java: -------------------------------------------------------------------------------- 1 | package kilim.test.ex; 2 | 3 | public class ExException extends Exception { 4 | private static final long serialVersionUID = 1L; 5 | 6 | public ExException(String message) { 7 | super(message); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/kilim/test/ex/ExFlow.java: -------------------------------------------------------------------------------- 1 | package kilim.test.ex; 2 | import kilim.Pausable; 3 | public class ExFlow { 4 | void loop() throws Pausable { 5 | ExA a = null; 6 | int i; 7 | for (i = 0; i < 10; i++) { 8 | if (i < 5) { 9 | a = new ExC(); 10 | } else { 11 | a = new ExD();; 12 | } 13 | } 14 | // at join, the stack must have types of [I,Lkilim.test.ex.ExFlow; and Lkilim.test.ex.ExA; 15 | // local vars-> 0:Lkilim.test.ex.ExFlow; 1:Lkilim.test.ex.ExA; 2:int 3:UNDEFINED 16 | int x = 10 * join(a); 17 | System.out.println(i); 18 | System.out.println(x); 19 | } 20 | 21 | int join(ExA a) throws Pausable { return 10;} 22 | } -------------------------------------------------------------------------------- /test/kilim/test/ex/ExFrame.java: -------------------------------------------------------------------------------- 1 | package kilim.test.ex; 2 | 3 | public class ExFrame { 4 | double[] kitchensink(int i, long j, boolean b, double d, String[][] s) { 5 | return null; 6 | } 7 | } -------------------------------------------------------------------------------- /test/kilim/test/ex/ExGenerics.java: -------------------------------------------------------------------------------- 1 | package kilim.test.ex; 2 | 3 | import kilim.Pausable; 4 | 5 | public class ExGenerics extends ExYieldBase { 6 | 7 | public void execute() throws Pausable { 8 | doPause = false; 9 | test(); 10 | doPause = true; 11 | test(); 12 | } 13 | 14 | T foo() throws Pausable { 15 | return null; 16 | } 17 | 18 | static class ExGenericsConcrete extends ExGenerics { 19 | String foo() throws Pausable { 20 | String s = fs; 21 | if (doPause) { 22 | sleep(1); 23 | } 24 | return s; 25 | } 26 | } 27 | private void test() throws Pausable { 28 | ExGenericsConcrete eb = new ExGenericsConcrete(); 29 | verify(eb.foo()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test/kilim/test/ex/ExInterfaceGeneric.java: -------------------------------------------------------------------------------- 1 | package kilim.test.ex; 2 | 3 | import kilim.*; 4 | 5 | public interface ExInterfaceGeneric { 6 | T get() throws Pausable; 7 | } 8 | -------------------------------------------------------------------------------- /test/kilim/test/ex/ExInterfaceGenericTask.java: -------------------------------------------------------------------------------- 1 | package kilim.test.ex; 2 | 3 | import kilim.*; 4 | 5 | 6 | public class ExInterfaceGenericTask extends Task { 7 | final ExInterfaceGeneric cache; 8 | public String getResponse; 9 | 10 | public ExInterfaceGenericTask(ExInterfaceGeneric cacheValue ) { 11 | cache = cacheValue; 12 | } 13 | 14 | public void execute() throws Pausable { 15 | getResponse = cache.get(); 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /test/kilim/test/ex/ExInterfaceImpl.java: -------------------------------------------------------------------------------- 1 | package kilim.test.ex; 2 | 3 | import kilim.*; 4 | 5 | interface ExInterface { 6 | int foo(float f) throws Pausable; 7 | } 8 | 9 | public class ExInterfaceImpl extends Task implements ExInterface { 10 | public void execute() throws Pausable { 11 | foo(10.2f); 12 | } 13 | 14 | public int foo(float f) throws Pausable { 15 | Task.sleep(1000); 16 | 17 | return (int)f; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/kilim/test/ex/ExInvalid.java: -------------------------------------------------------------------------------- 1 | package kilim.test.ex; 2 | 3 | import kilim.Pausable; 4 | import kilim.Task; 5 | 6 | // Just a ununsed public class to make it easy to have a bunch of related test 7 | // classes in one file 8 | public class ExInvalid { 9 | } 10 | 11 | class ExInvalidConstructor { 12 | ExInvalidConstructor() throws Pausable {} 13 | } 14 | class ExInvalidConstructor2 { 15 | ExInvalidConstructor2() throws Exception { 16 | Task.sleep(1000); 17 | } 18 | } 19 | class ExInvalidConstructor3 { 20 | ExInvalidConstructor3() throws Pausable { 21 | Task.sleep(1000); 22 | } 23 | } 24 | class ExInvalidStaticBlock { 25 | static void foo() throws Pausable {} 26 | static { 27 | try { foo(); } 28 | catch (Exception ex) {} 29 | } 30 | } 31 | class ExInvalidCallP_NP { 32 | void foo() throws Pausable {} 33 | void bar() throws Exception { 34 | foo(); 35 | } 36 | } 37 | 38 | // illegal to override a non-pausable method with a pausable one 39 | class ExNPSuper { 40 | void foo() throws Exception {} 41 | } 42 | class ExInvalidPDerived extends ExNPSuper { 43 | void foo() throws Pausable {} 44 | } 45 | 46 | //illegal to override a pausable method with a non-pausable one 47 | class ExPSuper { 48 | void foo() throws Pausable {} 49 | } 50 | class ExInvalidNPDerived extends ExPSuper { 51 | void foo() { 52 | 53 | } 54 | } 55 | 56 | 57 | //------------------------------------------------ 58 | // Illegal to override an pausable interface method with a non-pausable one 59 | interface ExPFoo { 60 | void foo() throws Pausable; 61 | } 62 | interface ExInvalidNPFace extends ExPFoo { 63 | void foo(); 64 | } 65 | class ExInvalidNPImp implements ExPFoo { 66 | public void foo() { 67 | } 68 | } 69 | 70 | //------------------------------------------------ 71 | //Illegal to override a non-pausable interface method with a pausable one 72 | interface ExNPFoo { 73 | void foo() throws Exception; 74 | } 75 | class ExInvalidPImp implements ExNPFoo { 76 | public void foo() throws Pausable {} 77 | } 78 | interface ExInvalidPFace extends ExNPFoo { 79 | void foo() throws Pausable; 80 | } 81 | -------------------------------------------------------------------------------- /test/kilim/test/ex/ExInvalidSynchronized.java: -------------------------------------------------------------------------------- 1 | package kilim.test.ex; 2 | 3 | import kilim.Pausable; 4 | 5 | 6 | // Ensure we don't call a pausable method from within a synchronized block 7 | public class ExInvalidSynchronized { 8 | void foo() throws Pausable {} 9 | synchronized void sync() throws Pausable { 10 | foo(); 11 | } 12 | } 13 | 14 | class ExInvalidSynchronized1 { 15 | void foo() throws Pausable {} 16 | void sync() throws Pausable { 17 | synchronized(this) { 18 | foo(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test/kilim/test/ex/ExJSR.j: -------------------------------------------------------------------------------- 1 | .class public kilim/test/ex/ExJSR 2 | .super java/lang/Object 3 | 4 | .method public ()V 5 | aload 0 6 | 7 | invokenonvirtual java/lang/Object/()V 8 | return 9 | .end method 10 | 11 | 12 | ;; -------------------------------------------- 13 | ;; Make a single jsr call that simply returns 14 | ;; -------------------------------------------- 15 | .method private static simpleJSR()V 16 | .limit locals 3 17 | .limit stack 3 18 | 19 | bipush 100 20 | istore 1 21 | jsr D 22 | iload 1 23 | istore 0 24 | return 25 | 26 | D: 27 | astore 2 28 | ret 2 29 | 30 | .end method 31 | 32 | ;; -------------------------------------------- 33 | ;; Single jsr call that calls pausable method 34 | ;; The number of basic blocks should be 4 35 | ;; -------------------------------------------- 36 | .method private static pausableJSR1()V 37 | .throws kilim/Pausable 38 | .limit locals 3 39 | .limit stack 3 40 | ;; BB 0 41 | bipush 100 42 | istore 1 43 | jsr D 44 | ;; BB 1 45 | iload 1 46 | istore 0 47 | return 48 | 49 | D: 50 | ;; BB 2 51 | astore 2 52 | ;; BB 3 53 | invokestatic kilim/test/ex/ExBasicBlock/pausable()V 54 | ret 2 55 | 56 | .end method 57 | 58 | 59 | ;; -------------------------------------------- 60 | ;; Multiple jsr calls to a pausable subr 61 | ;; The number of basic blocks should be 7 62 | ;; because the number of basic blocks without 63 | ;; inlining is 5, and inlining the second 64 | ;; jsr adds another two. 65 | ;; -------------------------------------------- 66 | .method private static pausableJSR2()V 67 | .throws kilim/Pausable 68 | .limit locals 3 69 | .limit stack 3 70 | 71 | bipush 100 72 | istore 1 73 | jsr D 74 | 75 | jsr D 76 | 77 | iload 1 78 | istore 0 79 | return 80 | D: 81 | astore 2 82 | invokestatic kilim/test/ex/ExBasicBlock/pausable()V 83 | ret 2 84 | 85 | .end method 86 | 87 | -------------------------------------------------------------------------------- /test/kilim/test/ex/ExLoop.java: -------------------------------------------------------------------------------- 1 | package kilim.test.ex; 2 | 3 | import kilim.Pausable; 4 | import kilim.Task; 5 | 6 | public class ExLoop extends Task { 7 | public String foo[] = new String[5]; 8 | String dummy() throws Pausable { 9 | Task.yield(); 10 | return "dummy"; 11 | } 12 | @Override 13 | public void execute() throws Pausable, Exception { 14 | for (int i = 0; i < foo.length; i++) { 15 | // foo and i are on the operand stack before dummy gets called. This 16 | // test checks that the operand stack is correctly restored. 17 | foo[i] = dummy(); 18 | } 19 | } 20 | 21 | public boolean verify() { 22 | // Call after ExLoop task has finished. foo[1..n] must have "dummy". 23 | for (int i = 0; i < foo.length; i++) { 24 | if (! "dummy".equals(foo[i])) { 25 | return false; 26 | } 27 | } 28 | return true; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/kilim/test/ex/ExPausable.java: -------------------------------------------------------------------------------- 1 | package kilim.test.ex; 2 | 3 | import kilim.Pausable; 4 | 5 | public class ExPausable { 6 | void noop() throws Pausable { 7 | 8 | } 9 | 10 | void simple() throws Pausable { 11 | noop(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/kilim/test/ex/ExTaskArgTypes.java: -------------------------------------------------------------------------------- 1 | package kilim.test.ex; 2 | 3 | import kilim.Pausable; 4 | import kilim.Task; 5 | 6 | public class ExTaskArgTypes extends Task { 7 | 8 | public void execute() throws Pausable { 9 | int i = 99; 10 | double d = Math.PI; 11 | String s = "foobar"; 12 | long l = Long.MAX_VALUE; 13 | float f = 10.5f; 14 | check(f, l, s, d, i); 15 | // Task.yield(); 16 | assert i == 99 : "Int wrong"; 17 | assert d == Math.PI: "Double wrong"; 18 | assert s == "foobar" : "String wrong"; 19 | assert l == Long.MAX_VALUE : "Long wrong"; 20 | assert f == 10.5f: "Float wrong"; 21 | Task.exit("Done"); 22 | } 23 | 24 | void check(float f, long l, Object s, double d, int i) throws Pausable { 25 | assert d == Math.PI; 26 | assert l == Long.MAX_VALUE; 27 | assert f == 10.5f; 28 | Task.yield(); 29 | assert i == 99; 30 | assert l == Long.MAX_VALUE; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test/kilim/test/ex/ExYieldBase.java: -------------------------------------------------------------------------------- 1 | package kilim.test.ex; 2 | 3 | import kilim.Task; 4 | 5 | public class ExYieldBase extends Task { 6 | public static int fi = 10; 7 | public static double fd = 10.0; 8 | public static long fl = 10L; 9 | public static float ff = 10.0f; 10 | public static char fc = 10; 11 | public static byte fb = 10; 12 | public static short fsh = 10; 13 | public static String fs = "10"; 14 | public static String[][] fa = { { "10" } }; 15 | 16 | public boolean doPause = false; 17 | 18 | public int testCase; // set by TestYield.runTask 19 | 20 | public static void verify(int i) { 21 | verify(i, fi); 22 | } 23 | 24 | public static void verify(int i, int compareTo) { 25 | if (i != compareTo) { 26 | throw new RuntimeException("i = " + i); 27 | } 28 | } 29 | 30 | public static void verify(short s, short compareTo) { 31 | if (s != compareTo) { 32 | throw new RuntimeException("s = " + s); 33 | } 34 | } 35 | 36 | public static void verify(short s) { 37 | verify(s, fsh); 38 | } 39 | 40 | 41 | public static void verify(double d) { 42 | verify(d, fd); 43 | } 44 | 45 | public static void verify(double d, double compareTo) { 46 | if (d != compareTo) { 47 | throw new RuntimeException("d = " + d); 48 | } 49 | } 50 | 51 | public static void verify(long l) { 52 | verify(l, fl); 53 | } 54 | 55 | public static void verify(long l, long compareTo) { 56 | if (l != compareTo) { 57 | throw new RuntimeException("l = " + l); 58 | } 59 | } 60 | 61 | public static void verify(char c) { 62 | if (c != fc) { 63 | throw new RuntimeException("c = " + c); 64 | } 65 | } 66 | 67 | 68 | public static void verify(float f) { 69 | verify(f, ff); 70 | } 71 | 72 | public static void verify(float f, float compareTo) { 73 | if (f != compareTo) { 74 | throw new RuntimeException("f = " + f); 75 | } 76 | } 77 | 78 | public static void verify(byte b) { 79 | if (b != fb) { 80 | throw new RuntimeException("b = " + b); 81 | } 82 | } 83 | 84 | public static void verify(String s) { 85 | if (s != fs) { 86 | throw new RuntimeException("s = " + s); 87 | } 88 | } 89 | 90 | public static void verify(String[][] a) { 91 | if (a != fa) { 92 | throw new RuntimeException("a = " + a); 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /test/kilim/test/ex/ExYieldConstants.java: -------------------------------------------------------------------------------- 1 | package kilim.test.ex; 2 | 3 | import kilim.Pausable; 4 | import kilim.Task; 5 | 6 | public class ExYieldConstants extends ExYieldBase { 7 | public ExYieldConstants(int test) { 8 | testCase = test; 9 | } 10 | 11 | public void execute() throws Pausable { 12 | doPause = false; 13 | testConstants(); 14 | doPause = true; 15 | testConstants(); 16 | } 17 | 18 | void testConstants() throws Pausable { 19 | double d0 = 0; 20 | double d1 = 1; 21 | double d = 10.0; 22 | int i0 = 0; 23 | long l0 = 0; 24 | long l1 = 1; 25 | long l = 10; 26 | int i1 = 1; 27 | int i2 = 2; 28 | int i3 = 3; 29 | int i4 = 4; 30 | int i5 = 5; 31 | float f0 = 0; 32 | float f1 = 1; 33 | int i = 10; 34 | String s = "10"; 35 | if (doPause) { 36 | Task.sleep(50); 37 | } 38 | pausable_st(d, s, l, doPause); 39 | new ExYieldConstants(testCase).pausable_v(d, s, l); 40 | verify(d); 41 | verify(l); 42 | verify(s); 43 | verify(i); 44 | // constants with built-in opcode support 45 | verify(f0, 0.0f); 46 | verify(f1, 1.0f); 47 | verify(d0, 0.0d); 48 | verify(d1, 1.0d); 49 | verify(i0, 0); 50 | verify(i1, 1); 51 | verify(i2, 2); 52 | verify(i3, 3); 53 | verify(i4, 4); 54 | verify(i5, 5); 55 | verify(l0, 0); 56 | verify(l1, 1); 57 | } 58 | 59 | static void pausable_st(double d, String s, long l, boolean doPause) throws Pausable { 60 | if (doPause) { 61 | Task.sleep(50); 62 | } 63 | verify(l); 64 | verify(s); 65 | verify(d); 66 | } 67 | 68 | void pausable_v(double d, String s, long l) throws Pausable { 69 | if (doPause) { 70 | Task.sleep(50); 71 | } 72 | verify(l); 73 | verify(s); 74 | verify(d); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /test/kilim/test/ex/ExYieldDups.java: -------------------------------------------------------------------------------- 1 | package kilim.test.ex; 2 | 3 | import kilim.Pausable; 4 | import kilim.Task; 5 | 6 | public class ExYieldDups extends ExYieldBase { 7 | public ExYieldDups(int test) { 8 | testCase = test; 9 | } 10 | 11 | public void execute() throws Pausable { 12 | doPause = false; 13 | test(); 14 | doPause = true; 15 | test(); 16 | } 17 | 18 | private void test() throws Pausable { 19 | switch(testCase) { 20 | case 0: testDupVars(); break; 21 | case 1: testDupsInStack(); break; 22 | case 2: testLongArgs(); break; 23 | default: throw new IllegalStateException("Unknown test case: " + testCase); 24 | } 25 | } 26 | 27 | 28 | 29 | void testLongArgs() throws Pausable { 30 | LongVal val = new LongVal(); 31 | useLongArg(fl,val); 32 | verify(val.msg); 33 | } 34 | 35 | static class LongVal { 36 | long msg; 37 | } 38 | 39 | // long and double values occupy 2 slots in the local variables table 40 | // the weaver needs to track this to be able to mark the arguments as in-use 41 | // test whether the weaver is correctly marking val as used after the pause 42 | void useLongArg(long index,LongVal val) throws Pausable { 43 | if (doPause) 44 | Task.sleep(50); 45 | val.msg = index; 46 | } 47 | 48 | 49 | void testDupVars() throws Pausable { 50 | double d = fd; 51 | double dup_d = d; 52 | long l = fl; 53 | long dup_l = l; 54 | String s = fs; 55 | String dup_s = s; 56 | if (doPause) { 57 | Task.sleep(50); 58 | } 59 | verify(d); 60 | verify(dup_d); 61 | verify(l); 62 | verify(dup_l); 63 | verify(s); 64 | verify(dup_s); 65 | } 66 | 67 | void testDupsInStack() throws Pausable { 68 | float f = ff; 69 | long l = fl; 70 | long dup_l = l; 71 | char c = fc; 72 | char dup_c = fc; 73 | float dup_f = f; 74 | verify(l, dup_l, c, dup_c, f, dup_f); 75 | if (doPause) { 76 | Task.sleep(50); 77 | } 78 | verify(f); 79 | verify(dup_f); 80 | verify(l); 81 | verify(dup_l); 82 | } 83 | 84 | 85 | static void verify(long l, long dup_l, char c, char dup_c, float f , float dup_f) { 86 | verify(l); 87 | verify(dup_l); 88 | verify(c); 89 | verify(dup_c); 90 | verify(f); 91 | verify(dup_f); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /test/kilim/test/ex/TaskStatusCB.java: -------------------------------------------------------------------------------- 1 | package kilim.test.ex; 2 | 3 | public interface TaskStatusCB { 4 | void beforeYield(); 5 | void afterYield(); 6 | void done(); 7 | } 8 | -------------------------------------------------------------------------------- /testing/README.md: -------------------------------------------------------------------------------- 1 | testing 2 | ======= 3 | 4 | the kilim tests are run as part of the build 5 | * that build environment differs from how user code is used 6 | * to simulate user code, this directory enables running those tests outside the kilim build 7 | 8 | 9 | `testing.sh`: 10 | * runs the kilim tests as an external project, with both runtime and ahead of time weaving 11 | * installs them as a woven artifact 12 | * runs them again as a dependency 13 | * ie, in the same way that user code is run 14 | * with a specified jdk home and pom 15 | 16 | 17 | note: `pom-test.xml` is for testing the installed artifact and is not a valid argument 18 | 19 | eg, run: 20 | 21 | JAVA_HOME=$java11 ./testing.sh pom11.xml 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /testing/java10/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /test 3 | -------------------------------------------------------------------------------- /testing/java10/pom-test.xml: -------------------------------------------------------------------------------- 1 | ../pom-test.xml -------------------------------------------------------------------------------- /testing/java10/pom10.xml: -------------------------------------------------------------------------------- 1 | ../pom10.xml -------------------------------------------------------------------------------- /testing/java10/src: -------------------------------------------------------------------------------- 1 | test -------------------------------------------------------------------------------- /testing/java10/test10.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # requires a patch from git, ie the tag java10 4 | 5 | 6 | dir=$(dirname "$0") 7 | cd "$dir" 8 | 9 | rsync -a --delete ../src/ test 10 | git show -p java10 -- ":(top)test" | patch -p1 11 | 12 | 13 | JAVA_HOME=$java10 ../testing.sh pom10.xml 14 | 15 | 16 | -------------------------------------------------------------------------------- /testing/pom-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | org.db4j 5 | kilim-tests-runner 6 | 0.1 7 | 8 | 9 | 10 | org.db4j 11 | kilim-tests 12 | 0.1 13 | 14 | 15 | 16 | 17 | 18 | org.codehaus.mojo 19 | exec-maven-plugin 20 | 1.6.0 21 | 22 | junit.textui.TestRunner 23 | kilim.test.AllWoven 24 | 25 | 26 | 27 | 28 | 29 | 1.8 30 | 1.8 31 | none 32 | 33 | 34 | -------------------------------------------------------------------------------- /testing/pom.xml: -------------------------------------------------------------------------------- 1 | pom8.xml -------------------------------------------------------------------------------- /testing/pom10.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | org.db4j 5 | kilim-tests 6 | 0.1 7 | 8 | 9 | 10 | org.db4j 11 | kilim 12 | 2.0.0-28-jdk10 13 | 14 | 15 | junit 16 | junit 17 | 3.8.1 18 | 19 | 20 | 21 | src 22 | 23 | 24 | org.db4j 25 | kilim 26 | 2.0.0-28-jdk10 27 | 28 | -q -x ExInvalid 29 | 30 | 31 | 32 | weave 33 | 34 | 35 | 36 | 37 | 38 | 39 | 10 40 | 10 41 | 10 42 | none 43 | 44 | 45 | -------------------------------------------------------------------------------- /testing/pom11.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | org.db4j 5 | kilim-tests 6 | 0.1 7 | 8 | 9 | 10 | org.db4j 11 | kilim 12 | 2.0.2 13 | 14 | 15 | junit 16 | junit 17 | 3.8.1 18 | 19 | 20 | 21 | src 22 | 23 | 24 | org.db4j 25 | kilim 26 | 2.0.2 27 | 28 | -q -x ExInvalid 29 | 30 | 31 | 32 | weave 33 | 34 | 35 | 36 | 37 | 38 | 39 | 11 40 | 11 41 | 11 42 | none 43 | 44 | 45 | -------------------------------------------------------------------------------- /testing/pom12.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | org.db4j 5 | kilim-tests 6 | 0.1 7 | 8 | 9 | 10 | org.db4j 11 | kilim 12 | 2.0.2 13 | 14 | 15 | junit 16 | junit 17 | 3.8.1 18 | 19 | 20 | 21 | src 22 | 23 | 24 | org.db4j 25 | kilim 26 | 2.0.2 27 | 28 | -q -x ExInvalid 29 | 30 | 31 | 32 | weave 33 | 34 | 35 | 36 | 37 | 38 | 39 | 12 40 | 12 41 | 12 42 | none 43 | 44 | 45 | -------------------------------------------------------------------------------- /testing/pom13.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | org.db4j 5 | kilim-tests 6 | 0.1 7 | 8 | 9 | 10 | org.db4j 11 | kilim 12 | 2.0.2 13 | 14 | 15 | junit 16 | junit 17 | 3.8.1 18 | 19 | 20 | 21 | src 22 | 23 | 24 | org.db4j 25 | kilim 26 | 2.0.2 27 | 28 | -q -x ExInvalid 29 | 30 | 31 | 32 | weave 33 | 34 | 35 | 36 | 37 | 38 | 39 | 13 40 | 13 41 | 13 42 | none 43 | 44 | 45 | -------------------------------------------------------------------------------- /testing/pom7.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | org.db4j 5 | kilim-tests 6 | 0.1 7 | 8 | 9 | 10 | org.db4j 11 | kilim 12 | 2.0.2-jdk7 13 | 14 | 15 | junit 16 | junit 17 | 3.8.1 18 | 19 | 20 | 21 | src 22 | 23 | 24 | org.apache.maven.plugins 25 | maven-compiler-plugin 26 | 27 | 28 | kilim/test/TestLambda.java 29 | 30 | 31 | 32 | 33 | org.db4j 34 | kilim 35 | 2.0.2-jdk7 36 | 37 | -q -x ExInvalid 38 | 39 | 40 | 41 | weave 42 | 43 | 44 | 45 | 46 | 47 | 48 | 1.7 49 | 1.7 50 | none 51 | 52 | 53 | -------------------------------------------------------------------------------- /testing/pom8.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | org.db4j 5 | kilim-tests 6 | 0.1 7 | 8 | 9 | 10 | org.db4j 11 | kilim 12 | 2.0.2 13 | 14 | 15 | junit 16 | junit 17 | 3.8.1 18 | 19 | 20 | 21 | src 22 | 23 | 24 | org.db4j 25 | kilim 26 | 2.0.2 27 | 28 | -q -x ExInvalid 29 | 30 | 31 | 32 | weave 33 | 34 | 35 | 36 | 37 | 38 | 39 | 1.8 40 | 1.8 41 | none 42 | 43 | 44 | -------------------------------------------------------------------------------- /testing/pom9.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | org.db4j 5 | kilim-tests 6 | 0.1 7 | 8 | 9 | 10 | org.db4j 11 | kilim 12 | 2.0.2 13 | 14 | 15 | junit 16 | junit 17 | 3.8.1 18 | 19 | 20 | 21 | src 22 | 23 | 24 | org.db4j 25 | kilim 26 | 2.0.2 27 | 28 | -q -x ExInvalid 29 | 30 | 31 | 32 | weave 33 | 34 | 35 | 36 | 37 | 38 | 39 | 1.9 40 | 1.9 41 | 9 42 | none 43 | 44 | 45 | -------------------------------------------------------------------------------- /testing/src: -------------------------------------------------------------------------------- 1 | ../test -------------------------------------------------------------------------------- /testing/testing.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | pom=$1 4 | 5 | [[ -f "$pom" ]] || { 6 | echo 7 | echo "usage: testing.sh pom" 8 | echo " run the kilim test suite as an external project" 9 | echo " with both runtime and ahead-of-time weaving" 10 | echo " install the resulting woven artifact" 11 | echo " and run the tests again as a dependency (see pom-test.xml)" 12 | echo 13 | echo "options:" 14 | echo " pom: required, a valid maven pom.xml" 15 | echo "env:" 16 | echo " JAVA_HOME: required, used by maven and to run ./bin/java" 17 | echo " MAVEN_HOME: optional, added to the path if set" 18 | echo "exit status:" 19 | echo " success if testjit and test both succeed" 20 | echo 21 | exit 1; 22 | } 23 | 24 | set -e 25 | 26 | if [ -n "$MAVEN_HOME" ]; then 27 | PATH="$MAVEN_HOME/bin:$PATH" 28 | fi 29 | 30 | 31 | mvn -f $pom -q clean compile 32 | cp=$(mvn -f $pom -q dependency:build-classpath -Dmdep.outputFile=/dev/fd/1) 33 | 34 | $JAVA_HOME/bin/java -ea -cp $cp kilim.tools.Asm -q -nf -d target/classes $(find src/ -name "*.j") > /dev/null 35 | 36 | mvn -f $pom -q exec:java -Dexec.mainClass=kilim.tools.Kilim -Dexec.args="junit.textui.TestRunner kilim.test.AllWoven" 37 | 38 | mvn -f $pom -q install 39 | 40 | mvn -f $pom -q exec:java -Dexec.mainClass=junit.textui.TestRunner -Dexec.args="kilim.test.AllWoven" 41 | 42 | tpom=$(dirname $pom)/pom-test.xml 43 | mvn -f $tpom -q exec:java 44 | 45 | --------------------------------------------------------------------------------