Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 258352

Summary: [Progress] synchronization in ProgressManager too expensive
Product: [Eclipse Project] Platform Reporter: Randall Theobald <rstheo>
Component: UIAssignee: Prakash Rangaraj <prakash>
Status: VERIFIED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: chrisri, edwinc, john.cortell, Kevin_McGuire, min123, pwebster, Tod_Creasey
Version: 3.4.1   
Target Milestone: 3.5 M5   
Hardware: PC   
OS: Windows XP   
Whiteboard:
Attachments:
Description Flags
proposed patch
rstheo: review?
Patch using ListenerList
none
Patch v02 pwebster: iplog+

Description Randall Theobald CLA 2008-12-10 15:15:42 EST
Created attachment 120102 [details]
proposed patch

Build ID: 3.4.1.M20080827-0800a


I am a performance analyst for an adopting product. During analysis of our forthcoming release (based on Eclipse 3.4.1), we observed a lot of stress on the 'listenersKey' lock in the class

    org.eclipse.ui.internal.progress.ProgressManager

for builds of a medium-sized workload. It turns out that this synchronization is rarely actually needed since the array it protects rarely changes. 

We can remove all the steady-state synchronization costs if we only synchronize when the array is altered (addListener/removeListener), use temporary arrays and then "flip the switch" when altering the array, and use temporary array references when iterating through the array unprotected. Since a new array is built for any change, unprotected iterations are safe as long as local references to the array are used.

I have attached a patch that accomplishes this.

A catch, though, when I made this change was that the listener ProgressViewUpdater seemed to be called much more frequently and ending up scheduling its 'updateJob' 115k times during import and build of the same medium-sized workload. This puts strain on the JobManager locks (see bug 258177). The patch also includes a small fix to make sure that the ProgressViewUpdater doesn't call schedule too often. With the patch, the 'updateJob' only scheduled itself about 1.4k times during import and build of the same workload.
Comment 1 Prakash Rangaraj CLA 2008-12-17 03:46:07 EST
Created attachment 120665 [details]
Patch using ListenerList

Randall,

     I've basically done the same thing thru the ListenerList class. Can you apply my patch and check whether this solves the problem?

Paul,
     This bug is raised against 3.4.1 Do we still have time to push in bugs for 3.4.2? Or should we target for 3.5?
Comment 2 Min Idzelis CLA 2008-12-17 09:04:15 EST
I notice that the new patch doesn't include the schedule delay. Is this just an oversight or is there some other reason to not include that portion of that original patch?

See https://bugs.eclipse.org/bugs/attachment.cgi?id=120102&action=diff#Eclipse%20UI/org/eclipse/ui/internal/progress/ProgressViewUpdater.java_sec1. 
Comment 3 Randall Theobald CLA 2008-12-17 09:31:17 EST
I'm fine with the implementation using the ListenerList, however, like Min mentioned, you dropped the changed to ProgressViewUpdater that limits the number of schedule calls. Is there a reason?
Comment 4 Prakash Rangaraj CLA 2008-12-17 12:12:02 EST
(In reply to comment #3)
> I'm fine with the implementation using the ListenerList, however, like Min
> mentioned, you dropped the changed to ProgressViewUpdater that limits the
> number of schedule calls. Is there a reason?

    First I wanted to make sure that the ListnerList stuff works (it didn't break any of our tests, but wanted to make sure of the performance) Will be adding that change as well.

Comment 5 Prakash Rangaraj CLA 2008-12-18 03:34:41 EST
(In reply to comment #3)
> I'm fine with the implementation using the ListenerList, however, like Min
> mentioned, you dropped the changed to ProgressViewUpdater that limits the
> number of schedule calls. Is there a reason?
> 

I did a small test for the schedule this:

long start = System.currentTimeMillis();
for(int i=0;i<115*1000;i++) {
	job.schedule(100);
}
long end = System.currentTimeMillis();
System.out.println("Time taken:"+(end-start)+"ms");

I ran it several times and on average scheduling a job 115k times takes 15 ms. Do we really have to optimize that out?
Comment 6 Min Idzelis CLA 2008-12-18 09:53:43 EST
Just chiming in again... uncontended synchronization in Java is very fast, in some books I've read they say that it basically free. However, contended synchronization is slow and gets slower with the number of simultaneous requests. In the workload the Randall and I have been working on, there an Auto Build and Validation is running in many many jobs. This puts a lot of strain on the ProgressManager and causes it to schedule even more jobs. 

Your test was done in a single thread where there is no chance for contention. If instead you created, say, 50-100 threads and each one of those threads was calling schedule on that job you may see some slower results due to contention. Additionally, you may need to have >1 core or >1 processor to experience the worst forms of contention. 

I would recommend avoiding the JobManager as much as possible in tight loops. 
Comment 7 Randall Theobald CLA 2008-12-18 11:20:35 EST
Yes, these calls are normally very fast, especially from the same thread (when there is no lock contention). However, on a system with a lot of load and a lot of threads/jobs, and with the requests spread across many threads, the cost of this definitely goes up. The contention spikes that I investigated were consistently on the locks in the Jobs infrastructure, so removal of any completely unnecessary grabbing of these locks would be good. I would vote yes, to optimize it. Optimizing all such UI-related updates to not occur more often than a human can consume them would help with general resource allocation.

Comment 8 Prakash Rangaraj CLA 2009-01-21 02:54:27 EST
Created attachment 123174 [details]
Patch v02

Patch using ListenerList + sync delay
Comment 9 Paul Webster CLA 2009-01-21 11:39:44 EST
(In reply to comment #8)
> Created an attachment (id=123174) [details]
> Patch v02

Released to HEAD >20090121
PW
Comment 10 Paul Webster CLA 2009-01-21 11:40:50 EST
.
Comment 11 Prakash Rangaraj CLA 2009-01-27 13:03:28 EST
Verified in I20090126-1800
Comment 12 John Cortell CLA 2012-12-03 18:21:05 EST
I believe this introduced a race condition bug in the Progress viewer. I've opened bug 395645