public class Concurrent
extends java.lang.Object
Modifier and Type | Field and Description |
---|---|
private static java.util.concurrent.ExecutorService |
execService
An executor service to run forkIO threads
|
private static java.util.concurrent.ForkJoinPool |
fjpool
The fork/join pool for ad hoc parallelism used by Frege runtime system..
|
private static java.lang.Object |
lock |
Constructor and Description |
---|
Concurrent() |
Modifier and Type | Method and Description |
---|---|
static java.util.concurrent.ExecutorService |
executorService()
Give access to the current executor service.
|
static <A> boolean |
fork(Func.U<java.lang.Boolean,A> f)
Evaluate
e in const e in parallel. |
static void |
notifyAll(java.lang.Object it)
Notify all threads that are waiting on the object
|
static void |
notifyOne(java.lang.Object it)
Notify exactly one thread that is waiting on the object
|
static java.util.concurrent.ExecutorService |
setFregeExecutorService(java.util.concurrent.ExecutorService svc)
Set the
ExecutorService that
should be used to run forkIO threads. |
static java.util.concurrent.ForkJoinPool |
setFregeForkJoinPool(java.util.concurrent.ForkJoinPool pool)
Set the
ForkJoinPool that should be used by the
Frege runtime. |
static void |
shutDownIfExists()
Shutdown the Frege Executor Service if it exists.
|
static void |
waitFor(java.lang.Object it)
Monitor wait on a given object.
|
private static java.lang.Object lock
private static java.util.concurrent.ForkJoinPool fjpool
Concurrent#setFregeForkJoindPool
private static java.util.concurrent.ExecutorService execService
An executor service to run forkIO threads
public static java.util.concurrent.ForkJoinPool setFregeForkJoinPool(java.util.concurrent.ForkJoinPool pool)
Set the ForkJoinPool
that should be used by the
Frege runtime.
pool
- - a fork/join pool to usepublic static java.util.concurrent.ExecutorService setFregeExecutorService(java.util.concurrent.ExecutorService svc)
Set the ExecutorService
that
should be used to run forkIO threads.
null
to query the
current executor service.
This should be used by external code that maintains its own
executor service
before calling into Frege code
to prevent creation of another executor service by the Frege runtime.
If the executorService()
finds no executor service, it will
create a fixed ThreadPoolExecutor
with a maximum
number of threads that equals 2 times the number of CPU cores available.svc
- - an executor service to usepublic static final <A> boolean fork(Func.U<java.lang.Boolean,A> f)
Evaluate e
in const e
in parallel.
This is a helper function for the `par` operator.
The argument is passed as Thunk
or Lazy
, which both
extend Callable
.
It then checks if we run in a ForkJoinPool
.
If this is so, it ForkJoinTask.fork()
s, causing the
delayed value to be evaluated asynchronously.
If we're not running in a ForkJoinPool
,
it checks if the pool
of the Frege runtime is already initialized.
If this is not the case, a new ForkJoinPool
will be created.
Finally, the delayed value will be submitted to the fork/join pool for asynchronous execution.
A Thunk
has the property that it prevents itself from being evaluated
more than once. It also blocks threads that attempt parallel execution.
Once evaluated, it remembers the result and subsequent invocations of
Thunk.call()
get the evaluated value immediately.
The success of parallel evaluation therefore depends on the time between construction of the delayed expression and the time when the value will actually be used. Ideally, it takes some CPU resources to evaluate a parallel computation, and it so happens that the value is only needed after it has been evaluated, to avoid wait time in the main thread.
val
- a Thunk
value to be evaluated in a fork/join context.
The Frege type system makes sure this is a pure computation.public static final java.util.concurrent.ExecutorService executorService()
Give access to the current executor service.
If the Frege executor service execService
is not
yet initialized, creates a fixed thread pool executor.
public static final void shutDownIfExists()
Shutdown the Frege Executor Service if it exists.
public static final void waitFor(java.lang.Object it) throws java.lang.InterruptedException
Monitor wait on a given object.
Because Object.wait(long)
must be run in a synchronized block,
we cannot just introduce it as a native function in Frege.
Basically, Frege does not know something like object identity. It is, however, guaranteed that, in the presence of a top level definition like:
object = "object to wait on"
the name object
will always refer to the same string object.
It is possible, that two top level values that evaluate to the same string value:
obj1 = "object" obj2 = "object"
could also be the same object at runtime, hence use different string constants if you want guaranteed different objects.
it
- - some objectjava.lang.InterruptedException
public static final void notifyOne(java.lang.Object it)
Notify exactly one thread that is waiting on the object
Because Object.notify()
must be run in a synchronized block,
we cannot just introduce this as native function in Frege.
See the discussion for waitFor(Object)
it
- - some objectpublic static final void notifyAll(java.lang.Object it)
Notify all threads that are waiting on the object
Because Object.notifyAll()
must be run in a synchronized block,
we cannot just introduce this as native function in Frege.
See the discussion for waitFor(Object)
it
- - some object