~ubuntu-branches/ubuntu/trusty/libgii/trusty

« back to all changes in this revision

Viewing changes to gg/time.c

  • Committer: Bazaar Package Importer
  • Author(s): Anibal Monsalve Salazar
  • Date: 2006-10-17 19:36:15 UTC
  • mfrom: (3.1.3 edgy)
  • Revision ID: james.westby@ubuntu.com-20061017193615-6civk5a1i4n1kyb0
Tags: 1:1.0.1-3
Fixed "ggtick is missing". Closes: #388682.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: time.c,v 1.9 2005/07/29 16:40:52 soyt Exp $
 
2
******************************************************************************
 
3
 
 
4
   platform abstraction of time related functions.
 
5
 
 
6
   Copyright (C) 2004  Brian S. Julin  [skids@users.sourceforge.net]
 
7
 
 
8
   Permission is hereby granted, free of charge, to any person obtaining a
 
9
   copy of this software and associated documentation files (the "Software"),
 
10
   to deal in the Software without restriction, including without limitation
 
11
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
 
12
   and/or sell copies of the Software, and to permit persons to whom the
 
13
   Software is furnished to do so, subject to the following conditions:
 
14
 
 
15
   The above copyright notice and this permission notice shall be included in
 
16
   all copies or substantial portions of the Software.
 
17
 
 
18
   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
19
   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
20
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 
21
   THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 
22
   IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
23
   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
24
 
 
25
******************************************************************************
 
26
*/
 
27
 
 
28
#include "config.h"
 
29
#include <ggi/gg.h>
 
30
#include <ggi/system.h>
 
31
 
 
32
#ifdef HAVE_UNISTD_H
 
33
#include <unistd.h>
 
34
#endif
 
35
 
 
36
#ifdef GG_CURTIME_USE_GETSYSTEMTIMEASFILETIME
 
37
#include <windows.h>
 
38
#endif
 
39
 
 
40
#ifdef HAVE_STDINT_H
 
41
#include <stdint.h>
 
42
#endif
 
43
 
 
44
/* Subtract timeval tv1 from timeval tv2, leaving the result in tv2. */
 
45
#define TVDIF(tv1, tv2) \
 
46
tv2.tv_sec -= tv1.tv_sec;                               \
 
47
if (tv2.tv_usec < tv1.tv_usec) {                        \
 
48
        tv2.tv_sec--;                                   \
 
49
        tv2.tv_usec += 1000000 - tv1.tv_usec;           \
 
50
} else tv2.tv_usec -= tv1.tv_usec;
 
51
 
 
52
 
 
53
/* Only one of the GG_USLEEP_USE_* macros will be defined by autoconf */
 
54
 
 
55
#ifdef GG_USLEEP_USE_USLEEP
 
56
 
 
57
/* LibC usleep implementation -- we must deal with different flavors */
 
58
 
 
59
#define GG_USLEEP_OK
 
60
 
 
61
#ifdef GG_USLEEP_999999
 
62
 
 
63
/* We have a pedantic usleep, so we have to split up calls into 1 sec chunks */
 
64
 
 
65
int ggUSleep (int32_t usecs) {
 
66
        struct timeval tv1, tv2;
 
67
        int usecs2;
 
68
 
 
69
        ggCurTime(&tv1);
 
70
        usecs2 = usecs;
 
71
        /* We could check each call for interrupt, but why bother,
 
72
         * since ggUSleep is interruptible.  Plus we don't have to
 
73
         * care about GG_USLEEP_VOID this way.
 
74
         */
 
75
        while (usecs2 >= 1000000) {
 
76
                usleep(999999);
 
77
                usecs2 -= 999999;
 
78
        }
 
79
        usleep(usecs2);
 
80
        ggCurTime(&tv2);
 
81
 
 
82
        TVDIF(tv1, tv2);
 
83
 
 
84
        if (tv2.tv_sec < usecs / 1000000) return -1;
 
85
        if (tv2.tv_usec < usecs % 1000000) return -1;
 
86
        return 0;
 
87
}
 
88
 
 
89
#else  /* not GG_USLEEP 999999 -- still have to adjust return type/value. */
 
90
 
 
91
#ifdef GG_USLEEP_VOID
 
92
 
 
93
int ggUSleep (int32_t usecs) {
 
94
        struct timeval tv1, tv2;
 
95
 
 
96
        ggCurTime(&tv1);
 
97
        usleep(usecs);
 
98
        ggCurTime(&tv2);
 
99
 
 
100
        TVDIF(tv1, tv2);
 
101
 
 
102
        if (tv2.tv_sec < usecs / 1000000) return -1;
 
103
        if (tv2.tv_usec < usecs % 1000000) return -1;
 
104
        return 0;
 
105
}
 
106
 
 
107
#else /* not GG_USLEEP_VOID -- simple C typecasting should suffice. */
 
108
 
 
109
int ggUSleep (int32_t usecs) {
 
110
        return (int)usleep(usecs);
 
111
}
 
112
 
 
113
#endif /* not GG_USLEEP_VOID */
 
114
#endif /* not GG_USLEEP_999999 */
 
115
#endif /* GG_USLEEP_USE_USLEEP */
 
116
 
 
117
 
 
118
#ifdef GG_USLEEP_USE_W32SLEEP
 
119
 
 
120
/* Win32 implementation, when no usleep() is available i.e. mingw */
 
121
 
 
122
#define GG_USLEEP_OK
 
123
 
 
124
/* windows.h is included above */
 
125
 
 
126
int ggUSleep (int32_t usecs) {
 
127
        Sleep((usecs + 999) / 1000);
 
128
        return 0;
 
129
}
 
130
 
 
131
#endif
 
132
 
 
133
#ifdef GG_USLEEP_USE_SELECT
 
134
 
 
135
/* Unix select used as sleep -- when select doesn't choke on an empty fdset. */
 
136
 
 
137
#define GG_USLEEP_OK
 
138
 
 
139
#ifdef HAVE_SYS_TYPES_H
 
140
#include <sys/types.h>
 
141
#endif
 
142
 
 
143
int ggUSleep(int32_t usecs) {
 
144
        struct timeval tv;
 
145
        tv.tv_sec = usecs / 1000000; 
 
146
        tv.tv_usec = usecs % 1000000;
 
147
        select(0, NULL, NULL, NULL, &tv);
 
148
        if (tv.tv_usec || tv.tv_sec) return -1;
 
149
        return 0;
 
150
}
 
151
 
 
152
#endif /* GG_USLEEP_USE_SELECT */
 
153
 
 
154
#ifndef GG_USLEEP_OK
 
155
#error You need to implement ggUSleep on this platform!
 
156
#endif
 
157
 
 
158
 
 
159
 
 
160
/* Only one of the GG_CURTIME_USE_* macros will be defined by autoconf */
 
161
 
 
162
#ifdef GG_CURTIME_USE_GETTIMEOFDAY
 
163
 
 
164
/* Headers already included by gg.h since struct timeval needed there */
 
165
 
 
166
#define GG_CURTIME_OK
 
167
int ggCurTime(struct timeval *tv) { 
 
168
        return(gettimeofday((tv), NULL));
 
169
}
 
170
 
 
171
#endif
 
172
 
 
173
#ifdef GG_CURTIME_USE_GETSYSTEMTIMEASFILETIME
 
174
 
 
175
/* windows.h included above on w32.
 
176
 * Other headers already included by gg.h since struct timeval needed there. 
 
177
 */
 
178
 
 
179
#define GG_CURTIME_OK
 
180
int ggCurTime(struct timeval *tv) { 
 
181
        FILETIME ftim;
 
182
 
 
183
        GetSystemTimeAsFileTime(&ftim);
 
184
 
 
185
        (tv)->tv_sec =  (((LARGE_INTEGER *)(void *)(&ftim))->QuadPart
 
186
                                - GG_UINT64_C(116444736000000000)) / 10000000;
 
187
        (tv)->tv_usec = (((LARGE_INTEGER *)(void *)(&ftim))->QuadPart
 
188
                                % 10000000) / 10;
 
189
 
 
190
        return 0;
 
191
}
 
192
 
 
193
#endif
 
194
 
 
195
#ifndef GG_CURTIME_OK
 
196
#error You need to implement ggCurTime() for this system
 
197
#endif
 
198
 
 
199
 
 
200
/* Uninterruptible sleep is now easily implemented based on the above work. */
 
201
void ggUSlumber(int32_t usecs) {
 
202
        struct timeval tv1, tv2;
 
203
 
 
204
        ggCurTime(&tv1);
 
205
 
 
206
        while (ggUSleep(usecs)) {
 
207
                ggCurTime(&tv2);
 
208
                TVDIF(tv1, tv2);
 
209
                if (tv2.tv_sec > usecs / 1000000) return;
 
210
                if (tv2.tv_sec) usecs -= 1000000 * tv2.tv_sec;
 
211
                if (tv2.tv_usec > usecs) return;
 
212
                usecs -= tv2.tv_usec;
 
213
                ggCurTime(&tv1);
 
214
        }
 
215
}