]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/io/serial/v2_0/misc/timeout.inl
Initial revision
[karo-tx-redboot.git] / packages / io / serial / v2_0 / misc / timeout.inl
1 #ifndef CYGONCE_IO_SERIAL_MISC_TIMEOUT_INL
2 #define CYGONCE_IO_SERIAL_MISC_TIMEOUT_INL
3 //==========================================================================
4 //
5 //        timeout.inl
6 //
7 //        Simple timeout support for serial I/O testing.
8 //
9 //==========================================================================
10 //####ECOSGPLCOPYRIGHTBEGIN####
11 // -------------------------------------------
12 // This file is part of eCos, the Embedded Configurable Operating System.
13 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
14 //
15 // eCos is free software; you can redistribute it and/or modify it under
16 // the terms of the GNU General Public License as published by the Free
17 // Software Foundation; either version 2 or (at your option) any later version.
18 //
19 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
20 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
22 // for more details.
23 //
24 // You should have received a copy of the GNU General Public License along
25 // with eCos; if not, write to the Free Software Foundation, Inc.,
26 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27 //
28 // As a special exception, if other files instantiate templates or use macros
29 // or inline functions from this file, or you compile this file and link it
30 // with other works to produce a work based on this file, this file does not
31 // by itself cause the resulting work to be covered by the GNU General Public
32 // License. However the source code for this file must still be made available
33 // in accordance with section (3) of the GNU General Public License.
34 //
35 // This exception does not invalidate any other reasons why a work based on
36 // this file might be covered by the GNU General Public License.
37 //
38 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
39 // at http://sources.redhat.com/ecos/ecos-license/
40 // -------------------------------------------
41 //####ECOSGPLCOPYRIGHTEND####
42 //==========================================================================
43 //#####DESCRIPTIONBEGIN####
44 //
45 // Author(s):     gthomas
46 // Contributors:  gthomas
47 // Date:          1999-02-05
48 // Description:   Simple timeout functions
49 //####DESCRIPTIONEND####
50
51 // Timeout support
52
53 typedef void (timeout_fun)(void *);
54 #ifndef NTIMEOUTS
55 #define NTIMEOUTS 8
56 #endif
57 typedef struct {
58     cyg_int32     delta;  // Number of "ticks" in the future for this timeout
59     timeout_fun  *fun;    // Function to execute when it expires
60     void         *arg;    // Argument to pass when it does
61 } timeout_entry;
62 static timeout_entry timeouts[NTIMEOUTS];
63 static cyg_handle_t timeout_alarm_handle;
64 static cyg_alarm timeout_alarm;
65 static cyg_int32 last_delta;
66
67 static void
68 do_timeout(cyg_handle_t alarm, cyg_addrword_t data)
69 {
70     int i;
71     cyg_int32 min_delta;
72     timeout_entry *e = timeouts;
73     min_delta = 0x7FFFFFFF;  // Maxint
74     for (i = 0;  i < NTIMEOUTS;  i++, e++) {
75         if (e->delta) {
76             e->delta -= last_delta;
77             if (e->delta == 0) {
78                 // Time for this item to 'fire'
79                 (e->fun)(e->arg);
80             } else {
81                 if (e->delta < min_delta) min_delta = e->delta;
82             }
83         }
84     }
85     if (min_delta != 0x7FFFFFFF) {
86         // Still something to do, schedule it
87         cyg_alarm_initialize(timeout_alarm_handle, cyg_current_time()+min_delta, 0);
88         last_delta = min_delta;
89     }
90 }
91
92 static cyg_uint32
93 timeout(cyg_int32 delta, timeout_fun *fun, void *arg)
94 {
95     int i;
96     cyg_int32 min_delta;
97     static bool init = false;
98     timeout_entry *e = timeouts;
99     cyg_uint32 stamp;
100     if (!init) {
101         cyg_handle_t h;
102         cyg_clock_to_counter(cyg_real_time_clock(), &h);
103         cyg_alarm_create(h, do_timeout, 0, &timeout_alarm_handle, &timeout_alarm);
104         init = true;
105     }
106     stamp = 0;  // Assume no slots available
107     for (i = 0;  i < NTIMEOUTS;  i++, e++) {
108         if ((e->delta == 0) && (e->fun == 0)) {
109             // Free entry
110             e->delta = delta;
111             e->fun = fun;
112             e->arg = arg;
113             stamp = (cyg_uint32)e;
114             break;
115         }
116     }
117     e = timeouts;
118     min_delta = 0x7FFFFFFF;
119     for (i = 0;  i < NTIMEOUTS;  i++, e++) {
120         if (e->delta && (e->delta < min_delta)) min_delta = e->delta;
121     }
122     if (min_delta != 0x7FFFFFFF) {
123         // Still something to do, schedule it
124         cyg_alarm_initialize(timeout_alarm_handle, cyg_current_time()+min_delta, 0);
125         last_delta = min_delta;
126     }
127     return stamp;
128 }
129
130 static void
131 untimeout(cyg_uint32 stamp)
132 {
133     if (stamp != 0) {
134         timeout_entry *e = (timeout_entry *)stamp;
135         if (e->fun != 0) {
136             e->delta = 0;
137             e->fun = 0;
138             e->arg = 0;
139         }
140     }
141 }
142
143 #endif // CYGONCE_IO_SERIAL_MISC_TIMEOUT_INL