Difference between revisions of "Locking in JANA"

From GlueXWiki
Jump to: navigation, search
(Creating Histograms or TTrees)
(Plugin Processor Variables)
Line 8: Line 8:
  
 
* Do NOT use or modify any class member-variables that you define for your JEventProcessor (i.e. in header file), unless you are in a lock (or in init(), fini()).  These variables can be modified by other threads.  
 
* Do NOT use or modify any class member-variables that you define for your JEventProcessor (i.e. in header file), unless you are in a lock (or in init(), fini()).  These variables can be modified by other threads.  
** This ESPECIALLY includes data saved in brun(), that is read in evnt().  
+
** For data modified in brun(), it is sometimes unfeasible to work around this, such as when reading in calibration constants. As long as the run number doesn't change, this should still be OK (they should just be overwriting the same value).
** Or even better, don't have any in the first place: Reduce the amount of time spent in locks if at all possible. Use function-scope (local) variables instead.
+
** Just to be safe, have as few class member variables as possible, and reduce the amount of time spent in locks. In other words, use function-scope (local) variables instead.
 
*** Where possible of course.  E.g. you can't avoid it with histograms, but you need to lock to fill those anyway.
 
*** Where possible of course.  E.g. you can't avoid it with histograms, but you need to lock to fill those anyway.
  

Revision as of 15:58, 11 April 2016

Plugin Processor Variables

  • Do not place use any locks in JEventProcessor::init() or ::fini(): they are unnecessary, and a waste of time.
    • JANA is guaranteed to be single-threaded in these functions.
  • Do not use or modify any global variables, unless you are in a lock.
    • Or even better, don't have any in the first place. It's terrible programming practice.
  • Do NOT use or modify any class member-variables that you define for your JEventProcessor (i.e. in header file), unless you are in a lock (or in init(), fini()). These variables can be modified by other threads.
    • For data modified in brun(), it is sometimes unfeasible to work around this, such as when reading in calibration constants. As long as the run number doesn't change, this should still be OK (they should just be overwriting the same value).
    • Just to be safe, have as few class member variables as possible, and reduce the amount of time spent in locks. In other words, use function-scope (local) variables instead.
      • Where possible of course. E.g. you can't avoid it with histograms, but you need to lock to fill those anyway.

Creating Histograms or TTrees

  • If you are creating histograms or trees (outside of JEventProcessor::init() or ::fini()): Use the global ROOT JANA lock functions below.
    • This is because they depend on gDirectory being constant.
japp->RootWriteLock(); //ACQUIRE ROOT LOCK
japp->RootUnLock(); //RELEASE ROOT LOCK

Filling Histograms

  • If you are filling histograms, you do NOT need to grab the global ROOT JANA lock functions. Try to instead grab a lock with a smaller scope, so that other threads can write to other histograms that don't interfere with yours.
    • In you are directly in the plugin processor, there's a special function to do this, that locks for the current plugin only. It is:
japp->RootFillLock(this); //ACQUIRE ROOT FILL LOCK //this: JEventProcessor pointer
japp->RootFillUnLock(this); //RELEASE ROOT FILL LOCK //this: JEventProcessor pointer

Filling TTrees

  • If you are filling TTrees to the global ROOT file (i.e. hd_root.root), write to the TTrees with the global ROOT JANA lock functions below:
    • This is because TTree::Fill() periodically writes to the file, modifying it.
japp->RootWriteLock(); //ACQUIRE ROOT LOCK
japp->RootUnLock(); //RELEASE ROOT LOCK
  • If you are filling TTrees to a local ROOT file (i.e. NOT hd_root.root), you do NOT need to grab the global ROOT JANA lock functions. Try to instead grab a lock with a smaller scope, so that other threads can write to other trees that don't interfere with yours.
    • Grab the same for every tree that is written to the same output file. This is because TTree::Fill() periodically writes to the file, modifying it.
    • This can be done with:
japp->WriteLock("MyFileName"); //ACQUIRE FILE LOCK
japp->Unlock("MyFileName"); //RELEASE FILE LOCK