I am generating quite a lot of Alloys specifications (*.als files). For a medium-size problem I am trying to solve, I generated 1536 *.als files. In order to save time running all these files, I used the Java concurrency API (in particular ExecutorCompletionService
with Future
) to run n Alloy commands in parallel, where n is the number of available logical cores on the machine (in my case 4, for 2 CPUs with HyperThreading).
In this context, it sometimes happens that a command freezes and does not return any result within a "reasonable" delay, which I fixed to 5 seconds as each *.als is rather simple.
It is not clear for me
- if Alloy can actually be used in such a concurrent/parallel context? (I would expect it is possible, as my command rely on distincts
Module
) - how can I interrupt/stop a "frozen" command? My program can detect these frozen commands, then ignores them, and finally re-schedule them for a pre-defined (max) number of attempt. The good news is, I always managed to run those 1536 commands, usually after several attempts. The bad news is that I usually end up "freezing" my PC (i.e having up to 4 cores running up to 100%) after all these Alloy commands have completed (Note that my program (an Eclipse plugin) does not terminate at this point and continues executing). Killing the JVM "unfreeze" my PC, likely indicating that the "frozen" Alloy still run...
For the code, I wrote some ugly tricks to try to recover when I encountered the freeze problem. But basically, it looks like (more details):
for(MyClass c : myClasses) {
AlloyWrapper worker = new AlloyWrapper(c, ...);
tasks.add(worker);
ecs.submit(worker);
}
I dimensioned the executor ecs so that it should use all the cores/physical threads available on the machine.
As for the AlloyWrapper, it does this (more details):
The Allow wrapper basically generates input for Alloy (based on information contained in MyClass) and calls
Module world = CompUtil.parseEverything_fromFile(null, null, input.getAbsolutePath());
solution = TranslateAlloyToKodkod.execute_command(NOP, world.getAllReachableSigs(), world.getAllCommands().get(0), opt);
Tell me if you need more information.