Subversion Repositories shark

Rev

Rev 120 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
40 pj 1
/* Project:     OSLib
2
 * Description: The OS Construction Kit
3
 * Date:                1.6.2000
4
 * Idea by:             Luca Abeni & Gerardo Lamastra
5
 *
6
 * OSLib is an SO project aimed at developing a common, easy-to-use
7
 * low-level infrastructure for developing OS kernels and Embedded
8
 * Applications; it partially derives from the HARTIK project but it
9
 * currently is independently developed.
10
 *
11
 * OSLib is distributed under GPL License, and some of its code has
12
 * been derived from the Linux kernel source; also some important
13
 * ideas come from studying the DJGPP go32 extender.
14
 *
15
 * We acknowledge the Linux Community, Free Software Foundation,
16
 * D.J. Delorie and all the other developers who believe in the
17
 * freedom of software and ideas.
18
 *
19
 * For legalese, check out the included GPL license.
20
 */
21
 
120 giacomo 22
/* Added Advanced Timer Code
23
 *
24
 * Date:   8.4.2003
25
 * Author: Giacomo Guidi <giacomo@gandalf.sssup.it>
26
 *
27
 */
28
 
40 pj 29
/*      Time Event routines     (one shot mode) */
30
 
31
#include <ll/i386/stdlib.h>
32
#include <ll/i386/mem.h>
33
#include <ll/i386/pit.h>
131 giacomo 34
#include <ll/i386/advtimer.h>
35
 
40 pj 36
#include <ll/sys/ll/ll-data.h>
37
#include <ll/sys/ll/time.h>
38
#include <ll/sys/ll/event.h>
39
 
40
FILE(EventOneShot);
41
 
42
extern int activeInt;
43
int activeEvent;
44
 
45
extern BYTE frc;
46
 
47
extern struct event eventlist[MAX_EVENT];
48
extern WORD lastTime;
49
extern struct pitspec globalCounter;
50
 
51
extern struct event *freeevents;
52
extern struct event *firstevent;
53
 
54
extern void (*evt_prol) (void);
55
extern void (*evt_epil) (void);
56
 
120 giacomo 57
extern unsigned char use_tsc;
58
 
40 pj 59
/* TODO: oneshot_event_delete & oneshot_event_init... */
60
 
61
/* Switched to timespec */
62
int oneshot_event_post(struct timespec time, void (*handler) (void *p),
63
                       void *par)
64
{
65
    struct event *p;
66
    struct event *p1, *t;
67
    struct timespec now, tmp;
68
    int done;
69
    DWORD tnext;
70
 
71
    if (!freeevents) {
72
        return -1;
73
    }
74
    /* Extract from the ``free events'' queue */
75
    p = freeevents;
76
    freeevents = p->next;
77
 
78
    /* Fill the event fields */
79
    p->handler = handler;
80
    TIMESPEC_ASSIGN(&(p->time), &time);
81
    p->par = par;
82
 
83
    /* ...And insert it in the event queue!!! */
84
 
85
    t = NULL;
86
    done = 0;
87
    /* walk through list, finding spot, adjusting ticks parameter */
88
    for (p1 = firstevent; p1; p1 = t->next) {
89
        if (TIMESPEC_A_GT_B((&time), (&p1->time))) {
90
            t = p1;
91
        } else
92
            break;
93
    }
94
 
95
    /* adjust next entry */
96
    if (t) {
97
        t->next = p;
98
    } else {
99
        firstevent = p;
100
        if (!activeEvent) {
101
          ll_gettime(TIME_NEW, &now);
102
          if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
103
            NULL_TIMESPEC(&tmp);
104
          } else {
105
            SUBTIMESPEC(&(firstevent->time), &now, &tmp);
106
          }
107
          tnext = TIMESPEC2USEC(&tmp);
108
          tnext = (tnext * 1197) / 1000;
109
          pit_setconstant(0, tnext);
110
        }
111
    }
112
    p->next = p1;
113
 
114
    return p->index;
115
}
116
 
117
 
118
 
119
void oneshot_wake_up(void)
120
{                               /* CHANGE the NAME, please... */
121
    struct event *p = NULL, *pp;
122
    struct timespec now, ttmp;
123
    WORD tmp;
124
    DWORD tnext;
125
 
120 giacomo 126
    if (!use_tsc) {
127
 
128
        tmp = pit_read(frc);
129
        ADDPITSPEC((WORD) (lastTime - tmp), &globalCounter);
130
        lastTime = tmp;
40 pj 131
 
120 giacomo 132
        PITSPEC2TIMESPEC(&globalCounter, &now);
40 pj 133
 
120 giacomo 134
    } else {
135
 
131 giacomo 136
        ll_read_timespec(&now);
120 giacomo 137
 
138
    }
139
 
40 pj 140
    if (firstevent != NULL) {
141
        activeEvent = 1;
142
        if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
143
            if (!activeInt && evt_prol != NULL) {
144
                evt_prol();
145
            }
146
            activeInt++;
147
 
148
            for (p = firstevent; p != NULL; p = pp) {
149
                if ((p->time.tv_sec > now.tv_sec) ||
150
                    ((p->time.tv_sec == now.tv_sec)
151
                     && (p->time.tv_nsec > now.tv_nsec))) {
152
                    break;
153
                }
154
                pp = p->next;
155
                p->next = freeevents;
156
                freeevents = p;
157
                firstevent = pp;
158
                p->handler(p->par);
159
            }
160
 
161
            if (activeInt == 1 && evt_epil != NULL) {
162
                evt_epil();
163
            }
164
            activeInt--;
165
        }
166
 
120 giacomo 167
        if (!use_tsc) {
168
 
169
            tmp = pit_read(frc);
170
            ADDPITSPEC((WORD) (lastTime - tmp), &globalCounter);
171
            lastTime = tmp;
40 pj 172
 
120 giacomo 173
            PITSPEC2TIMESPEC(&globalCounter, &now);
40 pj 174
 
120 giacomo 175
        } else {
176
 
131 giacomo 177
            ll_read_timespec(&now);
120 giacomo 178
 
179
        }
180
 
181
 
40 pj 182
        if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
183
            NULL_TIMESPEC(&ttmp);
184
        } else {
185
            SUBTIMESPEC(&(firstevent->time), &now, &ttmp);
186
        }
187
        /*  SUBTIMESPEC(&(firstevent->time), &now, &ttmp); */
188
        tnext = TIMESPEC2USEC(&ttmp);
189
        tnext = (tnext * 1197) / 1000;
190
        pit_setconstant(0, tnext);
191
 
192
        activeEvent = 0;
193
    } else {
194
        pit_setconstant(0, 0xFFFF);
195
    }
196
}
197
 
198
int oneshot_event_delete(int index)
199
{
200
    struct event *p1, *t;
201
    struct timespec tmp, now;
202
    DWORD tnext;
203
    int firstdeleted = FALSE;
204
 
205
    t = NULL;
206
    /* walk through list, finding spot, adjusting ticks parameter */
207
 
208
    for (p1 = firstevent; (p1) && (index != p1->index); p1 = t->next) {
209
        t = p1;
210
    }
211
 
212
    if (p1 == NULL) {
213
        return -1;
214
    }
215
    if (t == NULL) {
216
        firstevent = p1->next;
217
        firstdeleted = TRUE;
218
    } else {
219
        t->next = p1->next;
220
    }
221
 
222
    p1->next = freeevents;
223
    freeevents = p1;
224
 
225
    if (!activeEvent) {
226
      if (firstevent == NULL) {
227
        pit_setconstant(0, 0xFFFF);
228
      } else {
229
        if (firstdeleted) {
230
          ll_gettime(TIME_NEW, &now);
231
          if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
232
            NULL_TIMESPEC(&tmp);
233
          } else {
234
            SUBTIMESPEC(&(firstevent->time), &now, &tmp);
235
          }
236
          /*SUBTIMESPEC(&now, &(firstevent->time), &tmp); */
237
          tnext = TIMESPEC2USEC(&tmp);
238
          tnext = (tnext * 1197) / 1000;
239
          pit_setconstant(0, tnext);
240
        }
241
      }
242
    }
243
    return 1;
244
}