MADNESS  version 0.9
worlddep.h
Go to the documentation of this file.
1 /*
2  This file is part of MADNESS.
3 
4  Copyright (C) 2007,2010 Oak Ridge National Laboratory
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 
20  For more information please contact:
21 
22  Robert J. Harrison
23  Oak Ridge National Laboratory
24  One Bethel Valley Road
25  P.O. Box 2008, MS-6367
26 
27  email: harrisonrj@ornl.gov
28  tel: 865-241-3937
29  fax: 865-572-0680
30 
31 
32  $Id$
33 */
34 
35 
36 #ifndef MADNESS_WORLD_WORLDDEP_H__INCLUDED
37 #define MADNESS_WORLD_WORLDDEP_H__INCLUDED
38 
41 
42 #include <madness/world/array.h>
45 #include <madness/world/worldfwd.h>
46 #include <typeinfo>
47 
48 namespace madness {
49 
52  public:
53  virtual void notify() = 0;
54 
55  virtual ~CallbackInterface() {}
56  };
57 
58 
61  private:
62  // Replaced atomic counter with critical section so that all
63  // data (callbacks and counter) were being consistently managed.
64  volatile int ndepend;
65 
66  static const int MAXCALLBACKS = 8;
68  mutable volatile callbackT callbacks;
69 
70  // Main design point is that since a callback might destroy
71  // this object, when callbacks are invoked we cannot be
72  // holding the lock and all necessary data must be on the
73  // stack (i.e., not from the object state).
74  void do_callbacks(callbackT& cb) const {
75  while (!cb.empty()) {
76  cb.front()->notify();
77  cb.pop();
78  }
79  }
80 
81  public:
82  DependencyInterface(int ndep = 0) : ndepend(ndep) {}
83 
85  int ndep() const {return ndepend;}
86 
88  bool probe() const {return ndep() == 0;}
89 
91  void notify() {dec();}
92 
95  callbackT cb;
96  {
97  ScopedMutex<Spinlock> obolus(this);
98  const_cast<callbackT&>(this->callbacks).push(callback);
99  if (probe()) {
100  cb = const_cast<callbackT&>(callbacks);
101  const_cast<callbackT&>(callbacks).clear();
102  }
103  }
104  do_callbacks(cb);
105  }
106 
108  void inc() {
109  ScopedMutex<Spinlock> obolus(this);
110  ndepend++;
111  }
112 
114  void dec() {
115  callbackT cb;
116  {
117  ScopedMutex<Spinlock> obolus(this);
118  if (--ndepend == 0) {
119  cb = const_cast<callbackT&>(callbacks);
120  const_cast<callbackT&>(callbacks).clear();
121  }
122  }
123  do_callbacks(cb);
124  }
125 
127 #ifdef MADNESS_ASSERTIONS_THROW
128  if(ndepend != 0)
129  error("DependencyInterface::~DependencyInterface(): ndepend =", ndepend);
130 #else
131  MADNESS_ASSERT(ndepend == 0);
132 #endif
133  }
134 
135  };
136 }
137 #endif // MADNESS_WORLD_WORLDDEP_H__INCLUDED
Mutex that is applied/released at start/end of a scope.
Definition: worldmutex.h:186
void error(const char *msg)
Definition: world.cc:128
void inc()
Increment the number of dependencies.
Definition: worlddep.h:108
DependencyInterface(int ndep=0)
Definition: worlddep.h:82
void notify()
Invoked by callbacks to notifiy of dependencies being satisfied.
Definition: worlddep.h:91
This class used for callbacks (e.g., for dependency tracking)
Definition: worlddep.h:51
bool probe() const
Returns true if ndepend == 0.
Definition: worlddep.h:88
virtual ~DependencyInterface()
Definition: worlddep.h:126
bool empty() const
Definition: array.h:530
A simple, fixed-size, stack.
Definition: array.h:499
Provides interface for tracking dependencies.
Definition: worlddep.h:60
int ndep() const
Returns the number of unsatisfied dependencies.
Definition: worlddep.h:85
virtual ~CallbackInterface()
Definition: worlddep.h:55
T & pop()
Definition: array.h:512
Implements Mutex, MutexFair, Spinlock, ConditionVariable.
T & front()
Definition: array.h:517
Spinlock using pthread spinlock operations.
Definition: worldmutex.h:200
Implements World.
Holds machinery to set up Functions/FuncImpls using various Factories and Interfaces.
Definition: chem/atomutil.cc:45
void dec()
Decrement the number of dependencies and invoke callback if ndepend=0.
Definition: worlddep.h:114
virtual void notify()=0
void register_callback(CallbackInterface *callback)
Registers a callback for when ndepend==0 , immediately invoked if ndepend==0.
Definition: worlddep.h:94