< prev index next >

src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java

Print this page

1265         /**
1266          * Returns the approximate number of tasks in the queue.
1267          */
1268         final int queueSize() {
1269             int unused = phase;             // for ordering effect
1270             return Math.max(top - base, 0); // ignore transient negative
1271         }
1272 
1273         /**
1274          * Pushes a task. Called only by owner or if already locked
1275          *
1276          * @param task the task; no-op if null
1277          * @param pool the pool to signal if was previously empty, else null
1278          * @param internal if caller owns this queue
1279          * @throws RejectedExecutionException if array could not be resized
1280          */
1281         final void push(ForkJoinTask<?> task, ForkJoinPool pool, boolean internal) {
1282             int s = top, b = base, m, cap, room; ForkJoinTask<?>[] a;
1283             if ((a = array) != null && (cap = a.length) > 0 && // else disabled
1284                 task != null) {
1285                 int pk = task.noUserHelp() + 1;             // prev slot offset
1286                 if ((room = (m = cap - 1) - (s - b)) >= 0) {
1287                     top = s + 1;
1288                     long pos = slotOffset(m & s);
1289                     if (!internal)
1290                         U.putReference(a, pos, task);       // inside lock
1291                     else
1292                         U.getAndSetReference(a, pos, task); // fully fenced
1293                     if (room == 0)                          // resize
1294                         growArray(a, cap, s);
1295                 }
1296                 if (!internal)
1297                     unlockPhase();
1298                 if (room < 0)
1299                     throw new RejectedExecutionException("Queue capacity exceeded");
1300                 if ((room == 0 || a[m & (s - pk)] == null) &&
1301                     pool != null)

1302                     pool.signalWork();   // may have appeared empty
1303             }
1304         }
1305 
1306         /**
1307          * Resizes the queue array unless out of memory.
1308          * @param a old array
1309          * @param cap old array capacity
1310          * @param s current top
1311          */
1312         private void growArray(ForkJoinTask<?>[] a, int cap, int s) {
1313             int newCap = cap << 1;
1314             if (a != null && a.length == cap && cap > 0 && newCap > 0) {
1315                 ForkJoinTask<?>[] newArray = null;
1316                 try {
1317                     newArray = new ForkJoinTask<?>[newCap];
1318                 } catch (OutOfMemoryError ex) {
1319                 }
1320                 if (newArray != null) {               // else throw on next push
1321                     int mask = cap - 1, newMask = newCap - 1;

1265         /**
1266          * Returns the approximate number of tasks in the queue.
1267          */
1268         final int queueSize() {
1269             int unused = phase;             // for ordering effect
1270             return Math.max(top - base, 0); // ignore transient negative
1271         }
1272 
1273         /**
1274          * Pushes a task. Called only by owner or if already locked
1275          *
1276          * @param task the task; no-op if null
1277          * @param pool the pool to signal if was previously empty, else null
1278          * @param internal if caller owns this queue
1279          * @throws RejectedExecutionException if array could not be resized
1280          */
1281         final void push(ForkJoinTask<?> task, ForkJoinPool pool, boolean internal) {
1282             int s = top, b = base, m, cap, room; ForkJoinTask<?>[] a;
1283             if ((a = array) != null && (cap = a.length) > 0 && // else disabled
1284                 task != null) {

1285                 if ((room = (m = cap - 1) - (s - b)) >= 0) {
1286                     top = s + 1;
1287                     long pos = slotOffset(m & s);
1288                     if (!internal)
1289                         U.putReference(a, pos, task);       // inside lock
1290                     else
1291                         U.getAndSetReference(a, pos, task); // fully fenced
1292                     if (room == 0)                          // resize
1293                         growArray(a, cap, s);
1294                 }
1295                 if (!internal)
1296                     unlockPhase();
1297                 if (room < 0)
1298                     throw new RejectedExecutionException("Queue capacity exceeded");
1299                 if (pool != null &&
1300                     (room == 0 ||
1301                      U.getReferenceVolatile(a, slotOffset(m & (s - 1))) == null))
1302                     pool.signalWork();   // may have appeared empty
1303             }
1304         }
1305 
1306         /**
1307          * Resizes the queue array unless out of memory.
1308          * @param a old array
1309          * @param cap old array capacity
1310          * @param s current top
1311          */
1312         private void growArray(ForkJoinTask<?>[] a, int cap, int s) {
1313             int newCap = cap << 1;
1314             if (a != null && a.length == cap && cap > 0 && newCap > 0) {
1315                 ForkJoinTask<?>[] newArray = null;
1316                 try {
1317                     newArray = new ForkJoinTask<?>[newCap];
1318                 } catch (OutOfMemoryError ex) {
1319                 }
1320                 if (newArray != null) {               // else throw on next push
1321                     int mask = cap - 1, newMask = newCap - 1;
< prev index next >