NEURON
octimer.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 
3 #if HAVE_IV
4 #include <Dispatch/iohandler.h>
5 #include <Dispatch/dispatcher.h>
6 
7 #include <stdio.h>
8 #include "oc2iv.h"
9 #include "objcmd.h"
10 #endif /* HAVE_IV */
11 #include "classreg.h"
12 
13 #ifdef MINGW
14 #include <windows.h>
15 #endif
16 
17 #if HAVE_IV
18 #if carbon || defined(MINGW)
19 class OcTimer {
20 #else
21 class OcTimer : public IOHandler {
22 #endif
23 public:
24  OcTimer(const char*);
25  OcTimer(Object*);
26  virtual ~OcTimer();
27 
28  virtual void timerExpired(long, long);
29  void start();
30  void stop();
31  double seconds();
32  void seconds(double);
33 private:
34  double seconds_;
35  HocCommand* hc_;
36 #if carbon
37  EventLoopTimerRef timer_;
38 #else
39 #ifdef MINGW
40  HANDLE wtimer_;
41  bool stopped_;
42 #else
43  bool stopped_;
44 #endif /* not MINGW */
45 #endif /*not carbon*/
46 };
47 
48 #if carbon
49 static void timer_proc(EventLoopTimerRef, void* v) {
50  ((OcTimer*)v)->timerExpired(0,0);
51 }
52 #endif
53 
54 #ifdef MINGW
55 static void CALLBACK callback(PVOID lpParameter, BOOLEAN TimerOrWaitFired) {
56  ((OcTimer*)lpParameter)->timerExpired(0,0);
57 }
58 #endif
59 
60 #endif /* HAVE_IV */
61 
62 static double t_seconds(void* v) {
63 #if HAVE_IV
64  OcTimer* t = (OcTimer*)v;
65  if (ifarg(1)) {
66  t->seconds(chkarg(1, 1e-6, 1e6));
67  }
68  return double(t->seconds());
69 #else
70  return 0.;
71 #endif /* HAVE_IV */
72 }
73 
74 static double t_start(void* v) {
75 #if HAVE_IV
76  OcTimer* t = (OcTimer*)v;
77  t->start();
78  return 0.;
79 #else
80  return 0.;
81 #endif /* HAVE_IV */
82 }
83 static double t_stop(void* v) {
84 #if HAVE_IV
85  OcTimer* t = (OcTimer*)v;
86  t->stop();
87  return 0.;
88 #else
89  return 0.;
90 #endif /* HAVE_IV */
91 }
92 static void* t_cons(Object*) {
93 #if HAVE_IV
94  if (hoc_is_object_arg(1)) {
95  return new OcTimer(*hoc_objgetarg(1));
96  } else {
97  return new OcTimer(gargstr(1));
98  }
99 #else
100  return nullptr;
101 #endif /* HAVE_IV */
102 }
103 static void t_destruct(void* v) {
104 #if HAVE_IV
105  OcTimer* t = (OcTimer*)v;
106  delete t;
107 #endif /* HAVE_IV */
108 }
109 
111  "seconds", t_seconds,
112  "start", t_start,
113  "end", t_stop,
114  0, 0
115 };
116 
117 void OcTimer_reg() {
118  class2oc("Timer", t_cons, t_destruct, t_members, NULL, NULL, NULL);
119 }
120 #if HAVE_IV
121 OcTimer::OcTimer(const char* cmd) {
122  hc_ = new HocCommand(cmd);
123  seconds_ = .5;
124 #if carbon
125  timer_ = 0;
126 #else
127 #ifdef MINGW
128  wtimer_ = NULL;
129  stopped_ = true;
130 #else
131  stopped_ = true;
132 #endif
133 #endif
134 }
135 OcTimer::OcTimer(Object* cmd) {
136  hc_ = new HocCommand(cmd);
137  seconds_ = .5;
138 #if carbon
139  timer_ = 0;
140 #else
141 #ifdef MINGW
142  wtimer_ = NULL;
143  stopped_ = true;
144 #else
145  stopped_ = true;
146 #endif
147 #endif
148 }
149 OcTimer::~OcTimer() {
150  stop();
151  delete hc_;
152 }
153 void OcTimer::start() {
154 #if carbon
155  if (timer_) { return; }
156  InstallEventLoopTimer(GetMainEventLoop(), seconds_, seconds_, timer_proc,
157  (void*)this, &timer_);
158 #else
159 #ifdef MINGW
160  stopped_ = false;
161  LARGE_INTEGER nsec100;
162  nsec100.QuadPart = (long long)(-seconds_*10000000.);
163  wtimer_ = CreateWaitableTimer(NULL, TRUE, NULL);
164  while (stopped_ == false) {
165  SetWaitableTimer(wtimer_, &nsec100, 0, NULL, NULL, 0);
166  hc_->execute();
167  WaitForSingleObject(wtimer_, INFINITE);
168  }
169  CloseHandle(wtimer_);
170  wtimer_ = NULL;
171 #else
172  long s = long(seconds_);
173  long us = long((seconds_ - double(s))*1000000.);
174  stopped_ = false;
175  Dispatcher::instance().startTimer(s, us, this);
176 #endif
177 #endif
178 }
179 void OcTimer::stop() {
180 #if carbon
181  if (timer_) {
182  RemoveEventLoopTimer(timer_);
183  timer_ = 0;
184  }
185 #else
186 #ifdef MINGW
187  stopped_ = true;
188 #else
189  stopped_ = true;
190  Dispatcher::instance().stopTimer(this);
191 #endif
192 #endif
193 }
194 void OcTimer::timerExpired(long, long) {
195 #if carbon
196 #else
197 #ifdef MINGW
198 #else
199  if (!stopped_) {
200  this->start();
201  }
202 #endif
203 #endif
204  // want it to be part of interval just like on mac
205  hc_->execute();
206 }
207 double OcTimer::seconds() {
208  return seconds_;
209 }
210 void OcTimer::seconds(double sec) {
211  seconds_ = sec;
212 }
213 #endif /* HAVE_IV */
static void * t_cons(Object *)
Definition: octimer.cpp:92
#define BOOLEAN
Definition: spdefs.h:107
#define TRUE
Definition: err.c:57
#define v
Definition: md1redef.h:4
static double t_stop(void *v)
Definition: octimer.cpp:83
#define e
Definition: passive0.cpp:24
#define gargstr
Definition: hocdec.h:14
void start()
Definition: hel2mos.cpp:205
Member_func t_members[]
Definition: octimer.cpp:110
long
Definition: netcvode.cpp:4792
static void t_destruct(void *v)
Definition: octimer.cpp:103
_CONST char * s
Definition: system.cpp:74
static double t_seconds(void *v)
Definition: octimer.cpp:62
void class2oc(const char *, void *(*cons)(Object *), void(*destruct)(void *), Member_func *, int(*checkpoint)(void **), Member_ret_obj_func *, Member_ret_str_func *)
Definition: hoc_oop.cpp:1581
void OcTimer_reg()
Definition: octimer.cpp:117
void stop()
Definition: hel2mos.cpp:209
static double t_start(void *v)
Definition: octimer.cpp:74
int ifarg(int)
Definition: code.cpp:1562
Definition: hocdec.h:226
sec
Definition: solve.cpp:885
int hoc_is_object_arg(int narg)
Definition: code.cpp:745
double t
Definition: init.cpp:123
Object ** hoc_objgetarg(int)
Definition: code.cpp:1568
return NULL
Definition: cabcode.cpp:461
double chkarg(int, double low, double high)
Definition: code2.cpp:608