]>
Commit | Line | Data |
---|---|---|
21fdfcc1 | 1 | /* Implementation of the SYSTEM_CLOCK intrinsic. |
748086b7 | 2 | Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. |
21fdfcc1 SK |
3 | |
4 | This file is part of the GNU Fortran 95 runtime library (libgfortran). | |
5 | ||
6 | Libgfortran is free software; you can redistribute it and/or | |
57dea9f6 | 7 | modify it under the terms of the GNU General Public |
21fdfcc1 | 8 | License as published by the Free Software Foundation; either |
748086b7 | 9 | version 3 of the License, or (at your option) any later version. |
21fdfcc1 SK |
10 | |
11 | Libgfortran 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 | |
57dea9f6 | 14 | GNU General Public License for more details. |
21fdfcc1 | 15 | |
748086b7 JJ |
16 | Under Section 7 of GPL version 3, you are granted additional |
17 | permissions described in the GCC Runtime Library Exception, version | |
18 | 3.1, as published by the Free Software Foundation. | |
19 | ||
20 | You should have received a copy of the GNU General Public License and | |
21 | a copy of the GCC Runtime Library Exception along with this program; | |
22 | see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
23 | <http://www.gnu.org/licenses/>. */ | |
21fdfcc1 | 24 | |
21fdfcc1 SK |
25 | #include "libgfortran.h" |
26 | ||
27 | #include <limits.h> | |
28 | ||
29 | #if defined(HAVE_SYS_TIME_H) && defined(HAVE_GETTIMEOFDAY) | |
30 | # include <sys/time.h> | |
31 | # define TCK 1000 | |
32 | #elif defined(HAVE_TIME_H) | |
33 | # include <time.h> | |
34 | # define TCK 1 | |
35 | #else | |
36 | #define TCK 0 | |
37 | #endif | |
38 | ||
39 | ||
7d7b8bfe RH |
40 | extern void system_clock_4 (GFC_INTEGER_4 *, GFC_INTEGER_4 *, GFC_INTEGER_4 *); |
41 | export_proto(system_clock_4); | |
42 | ||
43 | extern void system_clock_8 (GFC_INTEGER_8 *, GFC_INTEGER_8 *, GFC_INTEGER_8 *); | |
44 | export_proto(system_clock_8); | |
45 | ||
46 | ||
21fdfcc1 SK |
47 | /* prefix(system_clock_4) is the INTEGER(4) version of the SYSTEM_CLOCK |
48 | intrinsic subroutine. It returns the number of clock ticks for the current | |
49 | system time, the number of ticks per second, and the maximum possible value | |
50 | for COUNT. On the first call to SYSTEM_CLOCK, COUNT is set to zero. */ | |
51 | ||
52 | void | |
7d7b8bfe RH |
53 | system_clock_4(GFC_INTEGER_4 *count, GFC_INTEGER_4 *count_rate, |
54 | GFC_INTEGER_4 *count_max) | |
21fdfcc1 SK |
55 | { |
56 | GFC_INTEGER_4 cnt; | |
21fdfcc1 SK |
57 | GFC_INTEGER_4 mx; |
58 | ||
59 | #if defined(HAVE_SYS_TIME_H) && defined(HAVE_GETTIMEOFDAY) | |
60 | struct timeval tp1; | |
61 | struct timezone tzp; | |
5e805e44 JJ |
62 | |
63 | if (sizeof (tp1.tv_sec) < sizeof (GFC_INTEGER_4)) | |
64 | internal_error (NULL, "tv_sec too small"); | |
21fdfcc1 SK |
65 | |
66 | if (gettimeofday(&tp1, &tzp) == 0) | |
67 | { | |
5e805e44 JJ |
68 | GFC_UINTEGER_4 ucnt = (GFC_UINTEGER_4) tp1.tv_sec * TCK; |
69 | ucnt += (tp1.tv_usec + 500000 / TCK) / (1000000 / TCK); | |
70 | if (ucnt > GFC_INTEGER_4_HUGE) | |
71 | cnt = ucnt - GFC_INTEGER_4_HUGE - 1; | |
21fdfcc1 | 72 | else |
5e805e44 | 73 | cnt = ucnt; |
21fdfcc1 SK |
74 | mx = GFC_INTEGER_4_HUGE; |
75 | } | |
76 | else | |
77 | { | |
6b021536 AJ |
78 | if (count != NULL) |
79 | *count = - GFC_INTEGER_4_HUGE; | |
80 | if (count_rate != NULL) | |
81 | *count_rate = 0; | |
82 | if (count_max != NULL) | |
83 | *count_max = 0; | |
84 | return; | |
21fdfcc1 SK |
85 | } |
86 | #elif defined(HAVE_TIME_H) | |
5e805e44 | 87 | GFC_UINTEGER_4 ucnt; |
21fdfcc1 | 88 | |
5e805e44 JJ |
89 | if (sizeof (time_t) < sizeof (GFC_INTEGER_4)) |
90 | internal_error (NULL, "time_t too small"); | |
21fdfcc1 | 91 | |
5e805e44 JJ |
92 | ucnt = time (NULL); |
93 | if (ucnt > GFC_INTEGER_4_HUGE) | |
94 | cnt = ucnt - GFC_INTEGER_4_HUGE - 1; | |
21fdfcc1 | 95 | else |
5e805e44 JJ |
96 | cnt = ucnt; |
97 | mx = GFC_INTEGER_4_HUGE; | |
21fdfcc1 SK |
98 | #else |
99 | cnt = - GFC_INTEGER_4_HUGE; | |
100 | mx = 0; | |
101 | #endif | |
6b021536 AJ |
102 | if (count != NULL) |
103 | *count = cnt; | |
104 | if (count_rate != NULL) | |
105 | *count_rate = TCK; | |
106 | if (count_max != NULL) | |
107 | *count_max = mx; | |
21fdfcc1 SK |
108 | } |
109 | ||
110 | ||
111 | /* INTEGER(8) version of the above routine. */ | |
112 | ||
113 | void | |
7d7b8bfe | 114 | system_clock_8 (GFC_INTEGER_8 *count, GFC_INTEGER_8 *count_rate, |
5e805e44 | 115 | GFC_INTEGER_8 *count_max) |
21fdfcc1 SK |
116 | { |
117 | GFC_INTEGER_8 cnt; | |
21fdfcc1 SK |
118 | GFC_INTEGER_8 mx; |
119 | ||
120 | #if defined(HAVE_SYS_TIME_H) && defined(HAVE_GETTIMEOFDAY) | |
121 | struct timeval tp1; | |
122 | struct timezone tzp; | |
5e805e44 JJ |
123 | |
124 | if (sizeof (tp1.tv_sec) < sizeof (GFC_INTEGER_4)) | |
125 | internal_error (NULL, "tv_sec too small"); | |
21fdfcc1 SK |
126 | |
127 | if (gettimeofday(&tp1, &tzp) == 0) | |
128 | { | |
5e805e44 JJ |
129 | if (sizeof (tp1.tv_sec) < sizeof (GFC_INTEGER_8)) |
130 | { | |
131 | GFC_UINTEGER_4 ucnt = (GFC_UINTEGER_4) tp1.tv_sec * TCK; | |
132 | ucnt += (tp1.tv_usec + 500000 / TCK) / (1000000 / TCK); | |
133 | if (ucnt > GFC_INTEGER_4_HUGE) | |
134 | cnt = ucnt - GFC_INTEGER_4_HUGE - 1; | |
135 | else | |
136 | cnt = ucnt; | |
137 | mx = GFC_INTEGER_4_HUGE; | |
138 | } | |
21fdfcc1 | 139 | else |
5e805e44 JJ |
140 | { |
141 | GFC_UINTEGER_8 ucnt = (GFC_UINTEGER_8) tp1.tv_sec * TCK; | |
142 | ucnt += (tp1.tv_usec + 500000 / TCK) / (1000000 / TCK); | |
143 | if (ucnt > GFC_INTEGER_8_HUGE) | |
144 | cnt = ucnt - GFC_INTEGER_8_HUGE - 1; | |
145 | else | |
146 | cnt = ucnt; | |
147 | mx = GFC_INTEGER_8_HUGE; | |
148 | } | |
21fdfcc1 SK |
149 | } |
150 | else | |
151 | { | |
6b021536 AJ |
152 | if (count != NULL) |
153 | *count = - GFC_INTEGER_8_HUGE; | |
154 | if (count_rate != NULL) | |
155 | *count_rate = 0; | |
156 | if (count_max != NULL) | |
157 | *count_max = 0; | |
158 | ||
159 | return; | |
21fdfcc1 SK |
160 | } |
161 | #elif defined(HAVE_TIME_H) | |
5e805e44 JJ |
162 | if (sizeof (time_t) < sizeof (GFC_INTEGER_4)) |
163 | internal_error (NULL, "time_t too small"); | |
164 | else if (sizeof (time_t) == sizeof (GFC_INTEGER_4)) | |
21fdfcc1 | 165 | { |
5e805e44 JJ |
166 | GFC_UINTEGER_4 ucnt = time (NULL); |
167 | if (ucnt > GFC_INTEGER_4_HUGE) | |
168 | cnt = ucnt - GFC_INTEGER_4_HUGE - 1; | |
169 | else | |
170 | cnt = ucnt; | |
171 | mx = GFC_INTEGER_4_HUGE; | |
21fdfcc1 | 172 | } |
21fdfcc1 SK |
173 | else |
174 | { | |
5e805e44 JJ |
175 | GFC_UINTEGER_8 ucnt = time (NULL); |
176 | if (ucnt > GFC_INTEGER_8_HUGE) | |
177 | cnt = ucnt - GFC_INTEGER_8_HUGE - 1; | |
178 | else | |
179 | cnt = ucnt; | |
21fdfcc1 SK |
180 | mx = GFC_INTEGER_8_HUGE; |
181 | } | |
182 | #else | |
183 | cnt = - GFC_INTEGER_8_HUGE; | |
184 | mx = 0; | |
185 | #endif | |
186 | if (count != NULL) | |
187 | *count = cnt; | |
188 | if (count_rate != NULL) | |
189 | *count_rate = TCK; | |
190 | if (count_max != NULL) | |
191 | *count_max = mx; | |
192 | } |