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

Bug 283446

Summary: [Jobs] Need a way to get the active rule stack for a given thread
Product: [Eclipse Project] Platform Reporter: Min Idzelis <min123>
Component: RuntimeAssignee: John Arthorne <john.arthorne>
Status: RESOLVED FIXED QA Contact:
Severity: enhancement    
Priority: P3 CC: boris.gruschko, thatnitind
Version: 3.4.2   
Target Milestone: 3.6 M6   
Hardware: PC   
OS: Windows XP   
Whiteboard:
Bug Depends on:    
Bug Blocks: 228962, 287096    
Attachments:
Description Flags
API and implementation none

Description Min Idzelis CLA 2009-07-14 14:09:22 EDT
In order to fix bug 228962, or to make the fix for 262175 better, we need a way to get at the active "scheduling rule stack" for a given thread. 

Additionally, we'll need a way to atomically transfer a stack of scheduling rules to a different thread. 

I propose the following new API method:

IJobManager#transferRules(ISchedulingRule[] rules, Thread destination)
Comment 1 Min Idzelis CLA 2009-07-14 14:16:25 EDT
See related bug 283446
Comment 2 Boris Gruschko CLA 2009-07-15 05:03:30 EDT
What we really need is an API to get the outermost non-null rule on the rule stack. Right now it is not possible to get the outermost rule, if a thread becomes upgraded to a Job via beginRule().

However, the usage of this API should be marked with a ton of warning signs. Making such an API available calls for trouble because the users will be tempted to develop their own locking strategies.
Comment 3 John Arthorne CLA 2009-07-15 10:57:38 EDT
>What we really need is an API to get the outermost non-null rule on the rule
stack.

I'm not sure what "outermost" is on a stack, but a job only has one "active" rule, and that's held in the slot Job.schedulingRule. All other rules in the stack are subsets of that rule as defined by ISchedulingRule#contains, so that rule should be all you need. The problem seems to be that Job.schedulingRule isn't accurate in the case where the job was started with no rule and then acquired one via beginRule.
Comment 4 Boris Gruschko CLA 2009-07-15 11:51:06 EDT
Just to clarify: "outermost" is what you call "active" in your terminology.
Comment 5 John Arthorne CLA 2009-07-15 12:34:23 EDT
Thanks, that's what I thought but it's good to clarify ;) Outermost could also be interpreted as the top of the stack.

Comment 6 Min Idzelis CLA 2009-07-15 13:49:16 EDT
Maybe I was referring to an implementation detail. ThreadJob in fact has a field called "ruleStack." 

If all rules acquired must be contained within the outer rule (with the exception of null, which contains all) then I think just the "topmost, non null rule" should be all we need. 

However, what would be the behavior of the following code? Assume Job is started with no rule, and A.contains(B)

Job (rule=null)
  acquire A
  acquire B
  transfer A to Thread-1

Thread-1
  acquire B


Will Thread-1 be allowed to start? Or would you need some kind of multi-rule transfer mechanism? 
Comment 7 John Arthorne CLA 2009-07-15 16:27:40 EDT
> Will Thread-1 be allowed to start?

Yes. In this case A.contains(B) must be true because of the nested acquire in the original thread, so similarly the nested acquire will work in the new thread. Again, a thread only ever really "owns" a single rule. By doing so it implicitly owns every rule for which ownedRule.contains(otherRule) is true. All of these "sub-rules" are owned regardless of whether they are in the rule stack. The rule stack is just used to enforce beginRule/endRule pairs being correctly nested.
Comment 8 Min Idzelis CLA 2009-07-15 22:43:35 EDT
(In reply to comment #7)

Ok, great!

Just wanted to also point out bug 283446 mentioned in comment #2. That bug deals with the fact that when a Job doesn't realize when a rule is transferred to it if the transfer happens *after* it already started to wait for it. That is, if

Job (rule=null)
  acquire A (owned by Thread-1)
  --(start spin-loop waiting for A)

Thread-1
  transfer A to Job

Job doesn't realize that it now has A after the transfer and stays in its spin-loop. 

Perhaps these two enhancements can be made at the same time? 
Comment 9 Min Idzelis CLA 2009-07-15 22:48:09 EDT
Oops. The reference bug in both cases was wrong. Please refer to bug 283449. 
Comment 10 Min Idzelis CLA 2009-08-26 11:36:16 EDT
Just pinging this to see to request that this be committed to be fixed in Eclipse 3.6.  

I also want to call attention to bug 287096 which has some soft dependencies on this bug. Several adopters (Oracle/IBM) are hitting issues that can be fixed if this bug is fixed. 
Comment 11 Min Idzelis CLA 2009-10-27 15:52:07 EDT
I have a very preliminary implementation/proposal. This is a partial patch. Should be added to JobManager.java. getThreadJob() just gets the ThreadJob from the ImplicitJob's threadJobs map. 

public ISchedulingRule currentRule() {
  Thread current = Thread.currentThread();
  ISchedulingRule currentRule = null;
  synchronized (lock) {
    synchronized (implicitJobs) {
      ThreadJob job = implicitJobs.getThreadJob(current);
      if (job != null) {
        for (int i = 0; i < job.ruleStack.length; i++) {
          if (job.ruleStack[i] != null) {
            currentRule = job.ruleStack[i];
            break;
          }
        }
      } else {
        Job currentJob = currentJob();
        if (currentJob != null) {
          currentRule = currentJob.getRule();
        }
      }
    }
  }
  return currentRule;
}
Comment 12 John Arthorne CLA 2010-03-02 12:23:32 EST
Created attachment 160651 [details]
API and implementation
Comment 13 John Arthorne CLA 2010-03-02 12:24:51 EST
I have released this in HEAD, along with test suites in IJobManagerTest.