set the lock the task is waiting on, and re-add spinning tasks when a lock is released
[AROS.git] / workbench / demos / simple_timer.c
blob9e37e6015ec4eb06fc722c3805921092f095a6fe
1 /*
2 * Copyright (c) 1992 Commodore-Amiga, Inc.
3 *
4 * This example is provided in electronic form by Commodore-Amiga, Inc. for
5 * use with the "Amiga ROM Kernel Reference Manual: Devices", 3rd Edition,
6 * published by Addison-Wesley (ISBN 0-201-56775-X).
7 *
8 * The "Amiga ROM Kernel Reference Manual: Devices" contains additional
9 * information on the correct usage of the techniques and operating system
10 * functions presented in these examples. The source and executable code
11 * of these examples may only be distributed in free electronic form, via
12 * bulletin board or as part of a fully non-commercial and freely
13 * redistributable diskette. Both the source and executable code (including
14 * comments) must be included, without modification, in any copy. This
15 * example may not be published in printed form or distributed with any
16 * commercial product. However, the programming techniques and support
17 * routines set forth in these examples may be used in the development
18 * of original executable software products for Commodore Amiga computers.
20 * All other rights reserved.
22 * This example is provided "as-is" and is subject to change; no
23 * warranties are made. All use is at your own risk. No liability or
24 * responsibility is assumed.
26 *****************************************************************************
28 * Simple_Timer.c
30 * A simple example of using the timer device.
32 * Compile with SAS C 5.10: LC -b1 -cfistq -v -y -L
34 * Run from CLI only
37 #include <exec/types.h>
38 #include <exec/io.h>
39 #include <exec/memory.h>
40 #include <devices/timer.h>
42 #include <proto/exec.h>
43 #include <clib/alib_protos.h>
44 #include <proto/dos.h>
46 #include <stdio.h>
48 #ifdef LATTICE
49 int CXBRK(void) { return(0); } /* Disable Lattice CTRL/C handling */
50 int chkabort(void) { return(0); } /* really */
51 #endif
53 /* Our timer sub-routines */
54 void delete_timer (struct timerequest *);
55 LONG get_sys_time (struct timeval *);
56 LONG set_new_time (LONG);
57 void wait_for_timer(struct timerequest *, struct timeval *);
58 LONG time_delay ( struct timeval *, LONG );
59 struct timerequest *create_timer( ULONG );
60 void show_time (ULONG);
62 struct Library *TimerBase; /* to get at the time comparison functions */
64 /* manifest constants -- "never will change" */
65 #define SECSPERMIN (60)
66 #define SECSPERHOUR (60*60)
67 #define SECSPERDAY (60*60*24)
69 int main(int argc,char **argv)
71 LONG seconds;
72 struct timerequest *tr; /* IO block for timer commands */
73 struct timeval oldtimeval; /* timevals to store times */
74 struct timeval mytimeval;
75 struct timeval currentval;
77 printf("\nTimer test\n");
79 /* sleep for two seconds */
80 currentval.tv_secs = 2;
81 currentval.tv_micro = 0;
82 time_delay( &currentval, UNIT_VBLANK );
83 printf( "After 2 seconds delay\n" );
85 /* sleep for four seconds */
86 currentval.tv_secs = 4;
87 currentval.tv_micro = 0;
88 time_delay( &currentval, UNIT_VBLANK );
89 printf( "After 4 seconds delay\n" );
91 /* sleep for 500,000 micro-seconds = 1/2 second */
92 currentval.tv_secs = 0;
93 currentval.tv_micro = 500000;
94 time_delay( &currentval, UNIT_MICROHZ );
95 printf( "After 1/2 second delay\n" );
97 printf( "DOS Date command shows: " );
98 (void) Execute( "date", 0, 0 );
100 /* save what system thinks is the time....we'll advance it temporarily */
101 get_sys_time( &oldtimeval );
102 printf("Original system time is:\n");
103 show_time(oldtimeval.tv_secs );
105 printf("Setting a new system time\n");
107 seconds = 1000 * SECSPERDAY + oldtimeval.tv_secs;
109 set_new_time( seconds );
110 /* (if user executes the AmigaDOS DATE command now, he will*/
111 /* see that the time has advanced something over 1000 days */
113 printf( "DOS Date command now shows: " );
114 (void) Execute( "date", 0, 0 );
116 get_sys_time( &mytimeval );
117 printf( "Current system time is:\n");
118 show_time(mytimeval.tv_secs);
120 /* Added the microseconds part to show that time keeps */
121 /* increasing even though you ask many times in a row */
123 printf("Now do three TR_GETSYSTIMEs in a row (notice how the microseconds increase)\n\n");
124 get_sys_time( &mytimeval );
125 printf("First TR_GETSYSTIME \t%ld.%ld\n",(long) mytimeval.tv_secs, (long) mytimeval.tv_micro);
126 get_sys_time( &mytimeval );
127 printf("Second TR_GETSYSTIME \t%ld.%ld\n",(long) mytimeval.tv_secs, (long) mytimeval.tv_micro);
128 get_sys_time( &mytimeval );
129 printf("Third TR_GETSYSTIME \t%ld.%ld\n",(long) mytimeval.tv_secs, (long) mytimeval.tv_micro);
131 printf( "\nResetting to former time\n" );
132 set_new_time( oldtimeval.tv_secs );
134 get_sys_time( &mytimeval );
135 printf( "Current system time is:\n");
136 show_time(mytimeval.tv_secs);
138 /* just shows how to set up for using the timer functions, does not */
139 /* demonstrate the functions themselves. (TimerBase must have a */
140 /* legal value before AddTime, SubTime or CmpTime are performed. */
141 tr = create_timer( UNIT_MICROHZ );
142 if (tr)
143 TimerBase = (struct Library *)tr->tr_node.io_Device;
144 else
145 printf("Could't create timer with UNIT_MICROHZ\n");
147 /* and how to clean up afterwards */
148 TimerBase = (struct Library *)(-1);
149 delete_timer( tr );
151 return 0;
154 struct timerequest *create_timer( ULONG unit )
156 /* return a pointer to a timer request. If any problem, return NULL */
157 LONG error;
158 struct MsgPort *timerport;
159 struct timerequest *TimerIO;
161 timerport = CreatePort( 0, 0 );
162 if (timerport == NULL )
163 return( NULL );
165 TimerIO = (struct timerequest *)
166 CreateExtIO( timerport, sizeof( struct timerequest ) );
167 if (TimerIO == NULL )
169 DeletePort(timerport); /* Delete message port */
170 return( NULL );
173 error = OpenDevice( TIMERNAME, unit,(struct IORequest *) TimerIO, 0L );
174 if (error != 0 )
176 delete_timer( TimerIO );
177 return( NULL );
179 return( TimerIO );
182 /* more precise timer than AmigaDOS Delay() */
183 LONG time_delay( struct timeval *tv, LONG unit )
185 struct timerequest *tr;
186 /* get a pointer to an initialized timer request block */
187 tr = create_timer( unit );
189 /* any nonzero return says timedelay routine didn't work. */
190 if (tr == NULL )
191 return( -1L );
193 wait_for_timer( tr, tv );
195 /* deallocate temporary structures */
196 delete_timer( tr );
197 return( 0L );
200 void wait_for_timer(struct timerequest *tr, struct timeval *tv )
203 tr->tr_node.io_Command = TR_ADDREQUEST; /* add a new timer request */
205 /* structure assignment */
206 tr->tr_time = *tv;
208 /* post request to the timer -- will go to sleep till done */
209 DoIO((struct IORequest *) tr );
212 LONG set_new_time(LONG secs)
214 struct timerequest *tr;
215 tr = create_timer( UNIT_MICROHZ );
217 /* non zero return says error */
218 if (tr == 0 )
219 return( -1 );
221 tr->tr_time.tv_secs = secs;
222 tr->tr_time.tv_micro = 0;
223 tr->tr_node.io_Command = TR_SETSYSTIME;
224 DoIO((struct IORequest *) tr );
226 delete_timer(tr);
227 return(0);
230 LONG get_sys_time(struct timeval *tv)
232 struct timerequest *tr;
233 tr = create_timer( UNIT_MICROHZ );
235 /* non zero return says error */
236 if (tr == 0 )
237 return( -1 );
239 tr->tr_node.io_Command = TR_GETSYSTIME;
240 DoIO((struct IORequest *) tr );
242 /* structure assignment */
243 *tv = tr->tr_time;
245 delete_timer( tr );
246 return( 0 );
249 void delete_timer(struct timerequest *tr )
251 struct MsgPort *tp;
253 if (tr != 0 )
255 tp = tr->tr_node.io_Message.mn_ReplyPort;
257 if (tp != 0)
258 DeletePort(tp);
260 CloseDevice( (struct IORequest *) tr );
261 DeleteExtIO( (struct IORequest *) tr );
265 void show_time(ULONG secs)
267 ULONG days,hrs,mins;
269 /* Compute days, hours, etc. */
270 mins=secs/60;
271 hrs=mins/60;
272 days=hrs/24;
273 secs=secs%60;
274 mins=mins%60;
275 hrs=hrs%24;
277 /* Display the time */
278 printf("* Hour Minute Second (Days since Jan.1,1978)\n");
279 printf("*%5ld:%5ld:%5ld (%6ld )\n\n",(long)hrs,(long)mins,(long)secs,(long)days);
280 } /* end of main */