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