Subversion Repositories shark

Rev

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