SCIP-SDP  4.0.0
sdpiclock.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of SCIPSDP - a solving framework for mixed-integer */
4 /* semidefinite programs based on SCIP. */
5 /* */
6 /* Copyright (C) 2011-2013 Discrete Optimization, TU Darmstadt */
7 /* EDOM, FAU Erlangen-Nürnberg */
8 /* 2014-2021 Discrete Optimization, TU Darmstadt */
9 /* */
10 /* */
11 /* This program is free software; you can redistribute it and/or */
12 /* modify it under the terms of the GNU Lesser General Public License */
13 /* as published by the Free Software Foundation; either version 3 */
14 /* of the License, or (at your option) any later version. */
15 /* */
16 /* This program is distributed in the hope that it will be useful, */
17 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
18 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
19 /* GNU Lesser General Public License for more details. */
20 /* */
21 /* You should have received a copy of the GNU Lesser General Public License */
22 /* along with this program; if not, write to the Free Software */
23 /* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.*/
24 /* */
25 /* */
26 /* Based on SCIP - Solving Constraint Integer Programs */
27 /* Copyright (C) 2002-2021 Zuse Institute Berlin */
28 /* SCIP is distributed under the terms of the SCIP Academic Licence, */
29 /* see file COPYING in the SCIP distribution. */
30 /* */
31 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
32 
42 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
43 
44 #include <assert.h>
45 #if defined(_WIN32) || defined(_WIN64)
46 #include <windows.h>
47 #else
48 #include <sys/times.h>
49 #include <sys/time.h>
50 #include <unistd.h>
51 #endif
52 #include <time.h>
53 
54 #include "scip/pub_message.h"
55 #include "blockmemshell/memory.h"
56 
57 #include "sdpi/sdpiclock.h"
58 #include "sdpi/struct_sdpiclock.h"
59 
60 
62 static
63 SCIP_Real cputime2sec(
64  clock_t cputime
65  )
66 {
67  clock_t clocks_per_second;
68 
69 #if defined(_WIN32) || defined(_WIN64)
70  clocks_per_second = 100;
71 #else
72 #ifndef CLK_TCK
73  clocks_per_second = sysconf(_SC_CLK_TCK);
74 #else
75  clocks_per_second = CLK_TCK;
76 #endif
77 #endif
78 
79  return (SCIP_Real)cputime / (SCIP_Real)clocks_per_second;
80 }
81 
82 /*lint -esym(*,timeval)*/
83 /*lint -esym(*,gettimeofday)*/
84 
86 static
87 SCIP_Real walltime2sec(
88  long sec,
89  long usec
90  )
91 {
92  return (SCIP_Real)sec + 0.000001 * (SCIP_Real)usec;
93 }
94 
96 SCIP_RETCODE SDPIclockCreate(
97  SDPI_CLOCK** clck
98  )
99 {
100  assert(clck != NULL);
101 
102  SCIP_ALLOC( BMSallocMemory(clck) );
103 
104  (*clck)->clocktype = SDPI_CLOCKTYPE_WALL;
105  (*clck)->nruns = 0;
106 
107  return SCIP_OKAY;
108 }
109 
112  SDPI_CLOCK** clck
113  )
114 {
115  assert(clck != NULL);
116 
117  BMSfreeMemory(clck);
118 }
119 
122  SDPI_CLOCK* clck,
123  SDPI_CLOCKTYPE clocktype
124  )
125 {
126  assert( clck != NULL );
127 
128  SCIPdebugMessage("setting type of clock %p to %d.\n", (void*)clck, clocktype);
129 
130  clck->clocktype = clocktype;
131 }
132 
135  SDPI_CLOCK* clck
136  )
137 {
138 #if defined(_WIN32) || defined(_WIN64)
139  FILETIME creationtime;
140  FILETIME exittime;
141  FILETIME kerneltime;
142  FILETIME usertime;
143 #else
144  struct timeval tp; /*lint !e86*/
145  struct tms now;
146 #endif
147 
148  assert( clck != NULL );
149  assert( clck->nruns == 0 );
150 
151  SCIPdebugMessage("starting clock %p (type %d).\n", (void*)clck, clck->clocktype);
152 
153  switch ( clck->clocktype )
154  {
155  case SDPI_CLOCKTYPE_CPU:
156 #if defined(_WIN32) || defined(_WIN64)
157  GetProcessTimes(GetCurrentProcess(), &creationtime, &exittime, &kerneltime, &usertime);
158  clck->data.cpuclock.user = - usertime.dwHighDateTime * 42950 + usertime.dwLowDateTime / 100000L;
159 #else
160  (void)times(&now);
161  clck->data.cpuclock.user = - now.tms_utime;
162 #endif
163  break;
164 
165  case SDPI_CLOCKTYPE_WALL:
166 #if defined(_WIN32) || defined(_WIN64)
167  clck->data.wallclock.sec = - time(NULL);
168 #else
169  gettimeofday(&tp, NULL);
170  if( tp.tv_usec > 0 ) /*lint !e115 !e40*/
171  {
172  clck->data.wallclock.sec = - (tp.tv_sec + 1); /*lint !e115 !e40*/
173  clck->data.wallclock.usec = (1000000 - tp.tv_usec); /*lint !e115 !e40*/
174  }
175  else
176  {
177  clck->data.wallclock.sec = - tp.tv_sec; /*lint !e115 !e40*/
178  clck->data.wallclock.usec = - tp.tv_usec; /*lint !e115 !e40*/
179  }
180 #endif
181  break;
182 
183  default:
184  SCIPerrorMessage("invalid clock type\n");
185  SCIPABORT();
186  }
187 
188  ++clck->nruns;
189 }
190 
193  SDPI_CLOCK* clck
194  )
195 {
196 #if defined(_WIN32) || defined(_WIN64)
197  FILETIME creationtime;
198  FILETIME exittime;
199  FILETIME kerneltime;
200  FILETIME usertime;
201 #else
202  struct timeval tp; /*lint !e86*/
203  struct tms now;
204 #endif
205 
206  assert( clck != NULL );
207  assert( clck->nruns == 1 );
208 
209  --clck->nruns;
210 
211  SCIPdebugMessage("stopping clock %p (type %d)\n", (void*)clck, clck->clocktype);
212 
213  switch ( clck->clocktype )
214  {
215  case SDPI_CLOCKTYPE_CPU:
216 #if defined(_WIN32) || defined(_WIN64)
217  GetProcessTimes(GetCurrentProcess(), &creationtime, &exittime, &kerneltime, &usertime);
218  clck->data.cpuclock.user += usertime.dwHighDateTime * 42950 + usertime.dwLowDateTime / 100000L;
219 #else
220  (void)times(&now);
221  clck->data.cpuclock.user += now.tms_utime;
222 #endif
223  break;
224 
225  case SDPI_CLOCKTYPE_WALL:
226 #if defined(_WIN32) || defined(_WIN64)
227  clck->data.wallclock.sec += time(NULL);
228 #else
229  gettimeofday(&tp, NULL);
230  if( tp.tv_usec + clck->data.wallclock.usec > 1000000 ) /*lint !e115 !e40*/
231  {
232  clck->data.wallclock.sec += (tp.tv_sec + 1); /*lint !e115 !e40*/
233  clck->data.wallclock.usec -= (1000000 - tp.tv_usec); /*lint !e115 !e40*/
234  }
235  else
236  {
237  clck->data.wallclock.sec += tp.tv_sec; /*lint !e115 !e40*/
238  clck->data.wallclock.usec += tp.tv_usec; /*lint !e115 !e40*/
239  }
240 #endif
241  break;
242 
243  default:
244  SCIPerrorMessage("invalid clock type\n");
245  SCIPABORT();
246  }
247 }
248 
251  SDPI_CLOCK* clck
252  )
253 {
254  SCIP_Real result = 0.0;
255 
256  assert( clck != NULL );
257 
258  SCIPdebugMessage("getting time of clock %p (type %d, nruns=%d)\n", (void*)clck, clck->clocktype, clck->nruns);
259 
260  if ( clck->nruns == 0 )
261  {
262  /* the clock is not running: convert the clocks timer into seconds */
263  switch ( clck->clocktype )
264  {
265  case SDPI_CLOCKTYPE_CPU:
266  result = cputime2sec(clck->data.cpuclock.user);
267  break;
268  case SDPI_CLOCKTYPE_WALL:
269  result = walltime2sec(clck->data.wallclock.sec, clck->data.wallclock.usec);
270  break;
271  default:
272  SCIPerrorMessage("invalid clock type\n");
273  SCIPABORT();
274  }
275  }
276  else
277  {
278 #if defined(_WIN32) || defined(_WIN64)
279  FILETIME creationtime;
280  FILETIME exittime;
281  FILETIME kerneltime;
282  FILETIME usertime;
283 #else
284  struct timeval tp; /*lint !e86*/
285  struct tms now;
286 #endif
287 
288  /* the clock is currently running: we have to add the current time to the clocks timer */
289  switch ( clck->clocktype )
290  {
291  case SDPI_CLOCKTYPE_CPU:
292 #if defined(_WIN32) || defined(_WIN64)
293  GetProcessTimes(GetCurrentProcess(), &creationtime, &exittime, &kerneltime, &usertime);
294  result = cputime2sec(clck->data.cpuclock.user + usertime.dwHighDateTime * 42950 + usertime.dwLowDateTime / 100000L);
295 #else
296  (void)times(&now);
297  result = cputime2sec(clck->data.cpuclock.user + now.tms_utime);
298 #endif
299  break;
300 
301  case SDPI_CLOCKTYPE_WALL:
302 #if defined(_WIN32) || defined(_WIN64)
303  result = walltime2sec(clck->data.wallclock.sec + time(NULL), 0);
304 #else
305  gettimeofday(&tp, NULL);
306  if( tp.tv_usec + clck->data.wallclock.usec > 1000000 ) /*lint !e115 !e40*/
307  result = walltime2sec(clck->data.wallclock.sec + tp.tv_sec + 1, (clck->data.wallclock.usec - 1000000) + tp.tv_usec); /*lint !e115 !e40*/
308  else
309  result = walltime2sec(clck->data.wallclock.sec + tp.tv_sec, clck->data.wallclock.usec + tp.tv_usec); /*lint !e115 !e40*/
310 #endif
311  break;
312 
313  default:
314  SCIPerrorMessage("invalid clock type\n");
315  SCIPABORT();
316  }
317  }
318 
319  return result;
320 }
SDPI_CPUCLOCK cpuclock
SDPI_WALLCLOCK wallclock
enum SDPI_ClockType SDPI_CLOCKTYPE
SDPI_CLOCKTYPE clocktype
static SCIP_Real cputime2sec(clock_t cputime)
Definition: sdpiclock.c:63
static SCIP_Real walltime2sec(long sec, long usec)
Definition: sdpiclock.c:87
void SDPIclockFree(SDPI_CLOCK **clck)
Definition: sdpiclock.c:111
SCIP_RETCODE SDPIclockCreate(SDPI_CLOCK **clck)
Definition: sdpiclock.c:96
void SDPIclockStop(SDPI_CLOCK *clck)
Definition: sdpiclock.c:192
void SDPIclockStart(SDPI_CLOCK *clck)
Definition: sdpiclock.c:134
datastructures for clocks and timing issues
void SDPIclockSetType(SDPI_CLOCK *clck, SDPI_CLOCKTYPE clocktype)
Definition: sdpiclock.c:121
SCIP_Real SDPIclockGetTime(SDPI_CLOCK *clck)
Definition: sdpiclock.c:250
union SDPI_Clock::@0 data
methods for clocks and timing