Difference between revisions of "Locking in JANA"

From GlueXWiki
Jump to: navigation, search
(Plugin Processor Variables)
(Plugin Processor Variables)
Line 1: Line 1:
 
=== Plugin Processor Variables ===
 
=== Plugin Processor Variables ===
  
* Do not place use any locks in JEventProcessor::init(): they are unnecessary, and a waste of time.
+
* 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 this function.  
+
** JANA is guaranteed to be single-threaded in these functions.  
  
 
* Do not use or modify any global variables, unless you are in a lock.  
 
* 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.  
 
** 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()).  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().  
 
** This ESPECIALLY includes data saved in brun(), that is read in evnt().  
 
** 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.
 
** 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.

Revision as of 11:07, 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.
    • This ESPECIALLY includes data saved in brun(), that is read in evnt().
    • 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.
      • 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()): 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