20 |
|
* cleanup methods surrounding the main task processing loop. If you |
21 |
|
* do create such a subclass, you will also need to supply a custom |
22 |
|
* ForkJoinWorkerThreadFactory to use it in a ForkJoinPool. |
23 |
< |
* |
23 |
> |
* |
24 |
|
*/ |
25 |
|
public class ForkJoinWorkerThread extends Thread { |
26 |
|
/* |
210 |
|
// Remaining initialization is deferred to onStart |
211 |
|
} |
212 |
|
|
213 |
< |
// Public access methods |
213 |
> |
// Public access methods |
214 |
|
|
215 |
|
/** |
216 |
|
* Returns the pool hosting this thread |
323 |
|
private void mainLoop() { |
324 |
|
while (!isShutdown()) { |
325 |
|
ForkJoinTask<?> t = pollTask(); |
326 |
< |
if (t != null || (t = pollSubmission()) != null) |
326 |
> |
if (t != null || (t = pollSubmission()) != null) |
327 |
|
t.quietlyExec(); |
328 |
|
else if (tryInactivate()) |
329 |
|
pool.sync(this); |
372 |
|
// propagate exception to uncaught exception handler |
373 |
|
try { |
374 |
|
do;while (!tryInactivate()); // ensure inactive |
375 |
< |
cancelTasks(); |
375 |
> |
cancelTasks(); |
376 |
|
runState = TERMINATED; |
377 |
|
pool.workerTerminated(this); |
378 |
|
} catch (Throwable ex) { // Shouldn't ever happen |
384 |
|
} |
385 |
|
} |
386 |
|
|
387 |
< |
// Intrinsics-based support for queue operations. |
387 |
> |
// Intrinsics-based support for queue operations. |
388 |
|
|
389 |
|
/** |
390 |
|
* Add in store-order the given task at given slot of q to |
665 |
|
} |
666 |
|
return t; |
667 |
|
} |
668 |
< |
|
668 |
> |
|
669 |
|
/** |
670 |
|
* Runs tasks until pool isQuiescent |
671 |
|
*/ |
672 |
|
final void helpQuiescePool() { |
673 |
|
for (;;) { |
674 |
|
ForkJoinTask<?> t = pollTask(); |
675 |
< |
if (t != null) |
675 |
> |
if (t != null) |
676 |
|
t.quietlyExec(); |
677 |
|
else if (tryInactivate() && pool.isQuiescent()) |
678 |
|
break; |
681 |
|
} |
682 |
|
|
683 |
|
// Temporary Unsafe mechanics for preliminary release |
684 |
+ |
private static Unsafe getUnsafe() throws Throwable { |
685 |
+ |
try { |
686 |
+ |
return Unsafe.getUnsafe(); |
687 |
+ |
} catch (SecurityException se) { |
688 |
+ |
try { |
689 |
+ |
return java.security.AccessController.doPrivileged |
690 |
+ |
(new java.security.PrivilegedExceptionAction<Unsafe>() { |
691 |
+ |
public Unsafe run() throws Exception { |
692 |
+ |
return getUnsafePrivileged(); |
693 |
+ |
}}); |
694 |
+ |
} catch (java.security.PrivilegedActionException e) { |
695 |
+ |
throw e.getCause(); |
696 |
+ |
} |
697 |
+ |
} |
698 |
+ |
} |
699 |
+ |
|
700 |
+ |
private static Unsafe getUnsafePrivileged() |
701 |
+ |
throws NoSuchFieldException, IllegalAccessException { |
702 |
+ |
Field f = Unsafe.class.getDeclaredField("theUnsafe"); |
703 |
+ |
f.setAccessible(true); |
704 |
+ |
return (Unsafe) f.get(null); |
705 |
+ |
} |
706 |
+ |
|
707 |
+ |
private static long fieldOffset(String fieldName) |
708 |
+ |
throws NoSuchFieldException { |
709 |
+ |
return _unsafe.objectFieldOffset |
710 |
+ |
(ForkJoinWorkerThread.class.getDeclaredField(fieldName)); |
711 |
+ |
} |
712 |
|
|
713 |
|
static final Unsafe _unsafe; |
714 |
|
static final long baseOffset; |
718 |
|
static final int qShift; |
719 |
|
static { |
720 |
|
try { |
721 |
< |
if (ForkJoinWorkerThread.class.getClassLoader() != null) { |
722 |
< |
Field f = Unsafe.class.getDeclaredField("theUnsafe"); |
723 |
< |
f.setAccessible(true); |
724 |
< |
_unsafe = (Unsafe)f.get(null); |
697 |
< |
} |
698 |
< |
else |
699 |
< |
_unsafe = Unsafe.getUnsafe(); |
700 |
< |
baseOffset = _unsafe.objectFieldOffset |
701 |
< |
(ForkJoinWorkerThread.class.getDeclaredField("base")); |
702 |
< |
spOffset = _unsafe.objectFieldOffset |
703 |
< |
(ForkJoinWorkerThread.class.getDeclaredField("sp")); |
704 |
< |
runStateOffset = _unsafe.objectFieldOffset |
705 |
< |
(ForkJoinWorkerThread.class.getDeclaredField("runState")); |
721 |
> |
_unsafe = getUnsafe(); |
722 |
> |
baseOffset = fieldOffset("base"); |
723 |
> |
spOffset = fieldOffset("sp"); |
724 |
> |
runStateOffset = fieldOffset("runState"); |
725 |
|
qBase = _unsafe.arrayBaseOffset(ForkJoinTask[].class); |
726 |
|
int s = _unsafe.arrayIndexScale(ForkJoinTask[].class); |
727 |
|
if ((s & (s-1)) != 0) |
728 |
|
throw new Error("data type scale not a power of two"); |
729 |
|
qShift = 31 - Integer.numberOfLeadingZeros(s); |
730 |
< |
} catch (Exception e) { |
730 |
> |
} catch (Throwable e) { |
731 |
|
throw new RuntimeException("Could not initialize intrinsics", e); |
732 |
|
} |
733 |
|
} |