Difference between revisions of "Locking in JANA"

From GlueXWiki
Jump to: navigation, search
(Created page with "* Do not place use any locks in JEventProcessor::init(), they are unnecessary, and a waste of time: JANA is guaranteed to be single-threaded in this function")
 
Line 1: Line 1:
* Do not place use any locks in JEventProcessor::init(), they are unnecessary, and a waste of time: JANA is guaranteed to be single-threaded in this function
+
* Do not place use any locks in JEventProcessor::init(): they are unnecessary, and a waste of time.
 +
** JANA is guaranteed to be single-threaded in this function.
 +
 
 +
* 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()).  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.
 +
 
 +
* If you are creating histograms or trees (outside of init()): Use the global ROOT JANA lock functions below.
 +
** This is because they depend on gDirectory being constant.
 +
<syntaxhighlight>
 +
japp->RootWriteLock(); //ACQUIRE ROOT LOCK
 +
japp->RootUnLock(); //RELEASE ROOT LOCK
 +
</syntaxhighlight>
 +
 
 +
=== 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:
 +
<syntaxhighlight>
 +
japp->RootFillLock(this); //ACQUIRE ROOT FILL LOCK //this: JEventProcessor pointer
 +
japp->RootFillUnLock(this); //RELEASE ROOT FILL LOCK //this: JEventProcessor pointer
 +
</syntaxhighlight>
 +
 
 +
=== 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.
 +
<syntaxhighlight>
 +
japp->RootWriteLock(); //ACQUIRE ROOT LOCK
 +
japp->RootUnLock(); //RELEASE ROOT LOCK
 +
</syntaxhighlight>
 +
 
 +
* 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:
 +
<syntaxhighlight>
 +
japp->WriteLock("MyFileName"); //ACQUIRE FILE LOCK
 +
japp->Unlock("MyFileName"); //RELEASE FILE LOCK
 +
</syntaxhighlight>

Revision as of 10:24, 11 April 2016

  • Do not place use any locks in JEventProcessor::init(): they are unnecessary, and a waste of time.
    • JANA is guaranteed to be single-threaded in this function.
  • 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()). 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.
  • If you are creating histograms or trees (outside of 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