View | Details | Raw Unified | Return to bug 570670 | Differences between
and this patch

Collapse All | Expand All

(-)a/plugins/org.eclipse.mat.parser/src/org/eclipse/mat/parser/internal/snapshot/ObjectMarker.java (-32 / +32 lines)
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()

Return to bug 570670