Lines 3-10
Link Here
|
3 |
* All rights reserved. This program and the accompanying materials |
3 |
* All rights reserved. This program and the accompanying materials |
4 |
* are made available under the terms of the Eclipse Public License 2.0 |
4 |
* are made available under the terms of the Eclipse Public License 2.0 |
5 |
* which accompanies this distribution, and is available at |
5 |
* which accompanies this distribution, and is available at |
6 |
* https://www.eclipse.org/legal/epl-2.0/ |
6 |
* https://www.eclipse.org/legal/epl-2.0/ |
7 |
* |
7 |
* |
8 |
* SPDX-License-Identifier: EPL-2.0 |
8 |
* SPDX-License-Identifier: EPL-2.0 |
9 |
* |
9 |
* |
10 |
* Contributors: |
10 |
* Contributors: |
Lines 63-121
public class ObjectMarker
Link Here
|
63 |
|
63 |
|
64 |
public class FjObjectMarker extends RecursiveAction |
64 |
public class FjObjectMarker extends RecursiveAction |
65 |
{ |
65 |
{ |
66 |
final int[] roots; |
66 |
final int position; |
67 |
final boolean[] visited; |
67 |
final boolean[] visited; |
68 |
final IIndexReader.IOne2ManyIndex outbound; |
|
|
69 |
final boolean topLevel; |
68 |
final boolean topLevel; |
70 |
|
69 |
|
71 |
private FjObjectMarker(final int[] roots, final boolean[] visited, final IIndexReader.IOne2ManyIndex outbound, |
70 |
int counter = 0; |
72 |
final boolean topLevel) |
71 |
|
|
|
72 |
private FjObjectMarker(final int position, final boolean[] visited, final boolean topLevel) |
73 |
{ |
73 |
{ |
74 |
this.roots = roots; |
74 |
// for the very root |
|
|
75 |
visited[position] = true; |
76 |
this.position = position; |
75 |
this.visited = visited; |
77 |
this.visited = visited; |
76 |
this.outbound = outbound; |
|
|
77 |
this.topLevel = topLevel; |
78 |
this.topLevel = topLevel; |
78 |
} |
79 |
} |
79 |
|
80 |
|
80 |
public void compute() |
81 |
public void compute() |
81 |
{ |
82 |
{ |
|
|
83 |
if (progressListener.isCanceled()) |
84 |
{ return; } |
85 |
|
86 |
compute(position, LEVELS_RUN_INLINE); |
87 |
|
82 |
if (topLevel) |
88 |
if (topLevel) |
83 |
{ |
89 |
{ |
84 |
// report progress only for top level tasks |
90 |
progressListener.worked(1); |
85 |
progressListener.beginTask(Messages.ObjectMarker_MarkingObjects, roots.length); |
|
|
86 |
compute(roots, LEVELS_RUN_INLINE); |
87 |
progressListener.done(); |
88 |
} else { |
89 |
compute(roots, LEVELS_RUN_INLINE); |
90 |
} |
91 |
} |
91 |
} |
92 |
} |
92 |
|
93 |
|
93 |
void compute(final int[] currentRoots, final int levelsLeft) |
94 |
public void compute(int outboundPosition, int levelsLeft) |
94 |
{ |
95 |
{ |
95 |
for (int r : currentRoots) |
96 |
final int[] process = outbound.get(outboundPosition); |
|
|
97 |
|
98 |
for (int r : process) |
96 |
{ |
99 |
{ |
97 |
// mark away |
|
|
98 |
if (!visited[r]) |
100 |
if (!visited[r]) |
99 |
{ |
101 |
{ |
100 |
visited[r] = true; |
102 |
visited[r] = true; |
101 |
int[] nextLevel = outbound.get(r); |
|
|
102 |
if (levelsLeft == 0) |
103 |
if (levelsLeft == 0) |
103 |
{ |
104 |
{ |
104 |
new FjObjectMarker(nextLevel, visited, outbound, false).fork(); |
105 |
new FjObjectMarker(r, visited, false).fork(); |
105 |
} |
106 |
} |
106 |
else |
107 |
else |
107 |
{ |
108 |
{ |
108 |
compute(nextLevel, levelsLeft - 1); |
109 |
compute(r, levelsLeft - 1); |
109 |
} |
110 |
} |
110 |
} |
111 |
} |
111 |
|
|
|
112 |
// update UI, check for stop |
113 |
if (topLevel) |
114 |
{ |
115 |
progressListener.worked(1); |
116 |
if (progressListener.isCanceled()) |
117 |
{ return; } |
118 |
} |
119 |
} |
112 |
} |
120 |
} |
113 |
} |
121 |
} |
114 |
} |
Lines 137-153
public class ObjectMarker
Link Here
|
137 |
|
130 |
|
138 |
public void markMultiThreaded(int threads) throws InterruptedException |
131 |
public void markMultiThreaded(int threads) throws InterruptedException |
139 |
{ |
132 |
{ |
140 |
// to control number of threads, and cleanly wait for comlpetion, create our own pool |
133 |
progressListener.beginTask(Messages.ObjectMarker_MarkingObjects, roots.length); |
141 |
// in theory this should automatically determined by FJ commonPool, however that |
134 |
|
142 |
// would break the interface specifying 'threads' |
135 |
// would break the interface specifying 'threads' |
143 |
ForkJoinPool pool = new ForkJoinPool(threads); |
136 |
ForkJoinPool pool = new ForkJoinPool(threads); |
144 |
pool.execute(new FjObjectMarker(roots, bits, outbound, true)); |
137 |
for (int r : roots) { |
|
|
138 |
// new FjObjectMarker(r, bits, true).invoke(); |
139 |
pool.execute(new FjObjectMarker(r, bits, true)); |
140 |
} |
145 |
pool.shutdown(); |
141 |
pool.shutdown(); |
146 |
while (!pool.awaitTermination(1000, TimeUnit.MILLISECONDS)) |
142 |
|
|
|
143 |
while (!pool.awaitTermination(60, TimeUnit.SECONDS)) |
147 |
{ |
144 |
{ |
|
|
145 |
System.out.println("waiting for ObjectMarker threads"); |
148 |
// being stuck here would be a bug; tasks are not ending |
146 |
// being stuck here would be a bug; tasks are not ending |
149 |
// TODO is there a heuristic that can be used to flag if no progress is made? |
147 |
// TODO is there a heuristic that can be used to flag if no progress is made? |
150 |
} |
148 |
} |
|
|
149 |
|
150 |
progressListener.done(); |
151 |
} |
151 |
} |
152 |
|
152 |
|
153 |
int countMarked() |
153 |
int countMarked() |