Subversion Repositories shark

Rev

Rev 40 | Rev 131 | Go to most recent revision | 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>
34
#include <ll/sys/ll/ll-data.h>
35
#include <ll/sys/ll/time.h>
36
#include <ll/sys/ll/event.h>
37
 
38
FILE(EventOneShot);
39
 
40
extern int activeInt;
41
int activeEvent;
42
 
43
extern BYTE frc;
44
 
45
extern struct event eventlist[MAX_EVENT];
46
extern WORD lastTime;
47
extern struct pitspec globalCounter;
48
 
49
extern struct event *freeevents;
50
extern struct event *firstevent;
51
 
52
extern void (*evt_prol) (void);
53
extern void (*evt_epil) (void);
54
 
120 giacomo 55
extern unsigned char use_tsc;
56
 
40 pj 57
/* TODO: oneshot_event_delete & oneshot_event_init... */
58
 
59
/* Switched to timespec */
60
int oneshot_event_post(struct timespec time, void (*handler) (void *p),
61
                       void *par)
62
{
63
    struct event *p;
64
    struct event *p1, *t;
65
    struct timespec now, tmp;
66
    int done;
67
    DWORD tnext;
68
 
69
    if (!freeevents) {
70
        return -1;
71
    }
72
    /* Extract from the ``free events'' queue */
73
    p = freeevents;
74
    freeevents = p->next;
75
 
76
    /* Fill the event fields */
77
    p->handler = handler;
78
    TIMESPEC_ASSIGN(&(p->time), &time);
79
    p->par = par;
80
 
81
    /* ...And insert it in the event queue!!! */
82
 
83
    t = NULL;
84
    done = 0;
85
    /* walk through list, finding spot, adjusting ticks parameter */
86
    for (p1 = firstevent; p1; p1 = t->next) {
87
        if (TIMESPEC_A_GT_B((&time), (&p1->time))) {
88
            t = p1;
89
        } else
90
            break;
91
    }
92
 
93
    /* adjust next entry */
94
    if (t) {
95
        t->next = p;
96
    } else {
97
        firstevent = p;
98
        if (!activeEvent) {
99
          ll_gettime(TIME_NEW, &now);
100
          if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
101
            NULL_TIMESPEC(&tmp);
102
          } else {
103
            SUBTIMESPEC(&(firstevent->time), &now, &tmp);
104
          }
105
          tnext = TIMESPEC2USEC(&tmp);
106
          tnext = (tnext * 1197) / 1000;
107
          pit_setconstant(0, tnext);
108
        }
109
    }
110
    p->next = p1;
111
 
112
    return p->index;
113
}
114
 
115
 
116
 
117
void oneshot_wake_up(void)
118
{                               /* CHANGE the NAME, please... */
119
    struct event *p = NULL, *pp;
120
    struct timespec now, ttmp;
121
    WORD tmp;
122
    DWORD tnext;
123
 
120 giacomo 124
    if (!use_tsc) {
125
 
126
        tmp = pit_read(frc);
127
        ADDPITSPEC((WORD) (lastTime - tmp), &globalCounter);
128
        lastTime = tmp;
40 pj 129
 
120 giacomo 130
        PITSPEC2TIMESPEC(&globalCounter, &now);
40 pj 131
 
120 giacomo 132
    } else {
133
 
134
        read_timespec(&now);
135
 
136
    }
137
 
40 pj 138
    if (firstevent != NULL) {
139
        activeEvent = 1;
140
        if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
141
            if (!activeInt && evt_prol != NULL) {
142
                evt_prol();
143
            }
144
            activeInt++;
145
 
146
            for (p = firstevent; p != NULL; p = pp) {
147
                if ((p->time.tv_sec > now.tv_sec) ||
148
                    ((p->time.tv_sec == now.tv_sec)
149
                     && (p->time.tv_nsec > now.tv_nsec))) {
150
                    break;
151
                }
152
                pp = p->next;
153
                p->next = freeevents;
154
                freeevents = p;
155
                firstevent = pp;
156
                p->handler(p->par);
157
            }
158
 
159
            if (activeInt == 1 && evt_epil != NULL) {
160
                evt_epil();
161
            }
162
            activeInt--;
163
        }
164
 
120 giacomo 165
        if (!use_tsc) {
166
 
167
            tmp = pit_read(frc);
168
            ADDPITSPEC((WORD) (lastTime - tmp), &globalCounter);
169
            lastTime = tmp;
40 pj 170
 
120 giacomo 171
            PITSPEC2TIMESPEC(&globalCounter, &now);
40 pj 172
 
120 giacomo 173
        } else {
174
 
175
            read_timespec(&now);
176
 
177
        }
178
 
179
 
40 pj 180
        if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
181
            NULL_TIMESPEC(&ttmp);
182
        } else {
183
            SUBTIMESPEC(&(firstevent->time), &now, &ttmp);
184
        }
185
        /*  SUBTIMESPEC(&(firstevent->time), &now, &ttmp); */
186
        tnext = TIMESPEC2USEC(&ttmp);
187
        tnext = (tnext * 1197) / 1000;
188
        pit_setconstant(0, tnext);
189
 
190
        activeEvent = 0;
191
    } else {
192
        pit_setconstant(0, 0xFFFF);
193
    }
194
}
195
 
196
int oneshot_event_delete(int index)
197
{
198
    struct event *p1, *t;
199
    struct timespec tmp, now;
200
    DWORD tnext;
201
    int firstdeleted = FALSE;
202
 
203
    t = NULL;
204
    /* walk through list, finding spot, adjusting ticks parameter */
205
 
206
    for (p1 = firstevent; (p1) && (index != p1->index); p1 = t->next) {
207
        t = p1;
208
    }
209
 
210
    if (p1 == NULL) {
211
        return -1;
212
    }
213
    if (t == NULL) {
214
        firstevent = p1->next;
215
        firstdeleted = TRUE;
216
    } else {
217
        t->next = p1->next;
218
    }
219
 
220
    p1->next = freeevents;
221
    freeevents = p1;
222
 
223
    if (!activeEvent) {
224
      if (firstevent == NULL) {
225
        pit_setconstant(0, 0xFFFF);
226
      } else {
227
        if (firstdeleted) {
228
          ll_gettime(TIME_NEW, &now);
229
          if (TIMESPEC_A_GT_B(&now, &(firstevent->time))) {
230
            NULL_TIMESPEC(&tmp);
231
          } else {
232
            SUBTIMESPEC(&(firstevent->time), &now, &tmp);
233
          }
234
          /*SUBTIMESPEC(&now, &(firstevent->time), &tmp); */
235
          tnext = TIMESPEC2USEC(&tmp);
236
          tnext = (tnext * 1197) / 1000;
237
          pit_setconstant(0, tnext);
238
        }
239
      }
240
    }
241
    return 1;
242
}