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 / +27 lines)
Lines 61-119 public class ObjectMarker Link Here
61
61
62
    public class FjObjectMarker extends RecursiveAction
62
    public class FjObjectMarker extends RecursiveAction
63
    {
63
    {
64
        final int[] roots;
64
        final int position;
65
        final boolean[] visited;
65
        final boolean[] visited;
66
        final IIndexReader.IOne2ManyIndex outbound;
67
        final boolean topLevel;
66
        final boolean topLevel;
68
67
69
        private FjObjectMarker(final int[] roots, final boolean[] visited, final IIndexReader.IOne2ManyIndex outbound,
68
        int counter = 0;
70
                        final boolean topLevel)
69
70
        private FjObjectMarker(final int position, final boolean[] visited, final boolean topLevel)
71
        {
71
        {
72
            this.roots = roots;
72
            // for the very root
73
            visited[position] = true;
74
            this.position = position;
73
            this.visited = visited;
75
            this.visited = visited;
74
            this.outbound = outbound;
75
            this.topLevel = topLevel;
76
            this.topLevel = topLevel;
76
        }
77
        }
77
78
78
        public void compute()
79
        public void compute()
79
        {
80
        {
81
            if (progressListener.isCanceled())
82
            { return; }
83
84
            compute(position, LEVELS_RUN_INLINE);
85
80
            if (topLevel)
86
            if (topLevel)
81
            {
87
            {
82
                // report progress only for top level tasks
88
                progressListener.worked(1);
83
                progressListener.beginTask(Messages.ObjectMarker_MarkingObjects, roots.length);
84
                compute(roots, LEVELS_RUN_INLINE);
85
                progressListener.done();
86
            } else {
87
                compute(roots, LEVELS_RUN_INLINE);
88
            }
89
            }
89
        }
90
        }
90
91
91
        void compute(final int[] currentRoots, final int levelsLeft)
92
        void compute(final int outboundPosition, final int levelsLeft)
92
        {
93
        {
93
            for (int r : currentRoots)
94
            final int[] process = outbound.get(outboundPosition);
95
96
            for (int r : process)
94
            {
97
            {
95
                // mark away
96
                if (!visited[r])
98
                if (!visited[r])
97
                {
99
                {
98
                    visited[r] = true;
100
                    visited[r] = true;
99
                    int[] nextLevel = outbound.get(r);
100
                    if (levelsLeft == 0)
101
                    if (levelsLeft == 0)
101
                    {
102
                    {
102
                        new FjObjectMarker(nextLevel, visited, outbound, false).fork();
103
                        new FjObjectMarker(r, visited, false).fork();
103
                    }
104
                    }
104
                    else
105
                    else
105
                    {
106
                    {
106
                        compute(nextLevel, levelsLeft - 1);
107
                        compute(r, levelsLeft - 1);
107
                    }
108
                    }
108
                }
109
                }
109
110
                // update UI, check for stop
111
                if (topLevel)
112
                {
113
                    progressListener.worked(1);
114
                    if (progressListener.isCanceled())
115
                    { return; }
116
                }
117
            }
110
            }
118
        }
111
        }
119
    }
112
    }
Lines 135-151 public class ObjectMarker Link Here
135
128
136
    public void markMultiThreaded(int threads) throws InterruptedException
129
    public void markMultiThreaded(int threads) throws InterruptedException
137
    {
130
    {
138
        // to control number of threads, and cleanly wait for comlpetion, create our own pool
131
        progressListener.beginTask(Messages.ObjectMarker_MarkingObjects, roots.length);
139
        // in theory this should automatically determined by FJ commonPool, however that
132
140
        // would break the interface specifying 'threads'
141
        ForkJoinPool pool = new ForkJoinPool(threads);
133
        ForkJoinPool pool = new ForkJoinPool(threads);
142
        pool.execute(new FjObjectMarker(roots, bits, outbound, true));
134
        for (int r : roots) {
135
            pool.execute(new FjObjectMarker(r, bits, true));
136
        }
143
        pool.shutdown();
137
        pool.shutdown();
144
        while (!pool.awaitTermination(1000, TimeUnit.MILLISECONDS))
138
        while (!pool.awaitTermination(1000, TimeUnit.MILLISECONDS))
145
        {
139
        {
146
            // being stuck here would be a bug; tasks are not ending
140
            // wait until completion
147
            // TODO is there a heuristic that can be used to flag if no progress is made?
148
        }
141
        }
142
143
        progressListener.done();
149
    }
144
    }
150
145
151
    int countMarked()
146
    int countMarked()

Return to bug 570670