-
Notifications
You must be signed in to change notification settings - Fork 0
/
laio_api.c
139 lines (132 loc) · 2.9 KB
/
laio_api.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/* $Id: laio_api.c,v 1.14 2004/06/23 19:07:46 kdiaa Exp $ */
#include <stdlib.h>
#include <errno.h>
#include <assert.h>
#include "upcall_handler.h"
#include "laio_api.h"
void *foo = NULL;
#if 0
int
laio_syscall(int number, ...)
{
if (!_setjmp(sched_data.env)) {
assert(current_thread);
sched_data.mb.km_curthread = current_thread;
thread_desc = current_thread;
//rv = syscall(number, arg_list);
//the asm code here
{asm (
" \
pop %ecx; \
pop %eax; \
push %ecx; \
int $0x80; \
push %ecx; \
jb 1f; \
jmp 2f; \
1: \
pushl %ebx; \
call 1f; \
1: \
popl %ebx; \
addl $_GLOBAL_OFFSET_TABLE_+[.-1b],%ebx; \
jmp .cerror@PLT; \
2: \
");
}
sched_data.mb.km_curthread = NULL;
thread_desc = (void *) 0;
asm("ret");
assert(0);
}
else {
laio_desc_bg = thread_desc;
errno = EINPROGRESS;
return (-1);
}
/* does not come here */
assert(0);
return (0);
}
#endif
void *
laio_gethandle(void)
{
return (laio_desc_bg);
}
int
laio_poll(struct laio_completion completions[], int ncompletions, const struct timespec *timeout)
{
struct kse_thr_mailbox *ktm = NULL;
int i;
if (completed_threads == NULL && ncompletions > 0) {
#if 0
/* we have to wait */
if (timeout == NULL) {
struct timespec ts = { 60, 0 };
/* enable upcalls */
if (nblocked_threads > 0) {
sched_data.mb.km_curthread = current_thread;
thr_in_laio_poll = current_thread;
}
/* infinite timeout */
for (;;) {
nanosleep(&ts, NULL);
if (completed_threads != NULL)
break;
}
/* disable upcalls */
sched_data.mb.km_curthread = NULL;
thr_in_laio_poll = NULL;
}
else {
long tv_time = timeout->tv_sec * 1000000000 + timeout->tv_nsec;
if (tv_time < 0) {
errno = EINVAL;
return (-1);
}
/* enable upcalls */
if (nblocked_threads > 0) {
sched_data.mb.km_curthread = current_thread;
thr_in_laio_poll = current_thread;
}
nanosleep(timeout, NULL);
/* disable upcalls */
sched_data.mb.km_curthread = NULL;
thr_in_laio_poll = NULL;
}
#endif
thr_in_laio_poll = current_thread;
if (!_setjmp(poll_data.env)) {
kse_release((struct timespec *) timeout);
/* cannot come here */
assert(0);
}
/*
* will come here when something unblocks or
* timer expires
*/
thr_in_laio_poll = NULL;
}
for (i = 0; i < ncompletions && completed_threads != NULL; i++) {
int ret;
ktm = completed_threads;
completed_threads = completed_threads->tm_next;
if (completed_threads == NULL)
completed_threads_tail = &completed_threads;
*free_threads_tail = ktm;
free_threads_tail = &ktm->tm_next;
ktm->tm_next = NULL;
completions[i].laio_h = ktm;
ret = ktm->tm_context.uc_mcontext.mc_eax;
if (ktm->tm_context.uc_mcontext.mc_eflags & CARRY_FLAG) {
completions[i].laio_rv = -1;
completions[i].laio_errno = ret;
}
else {
completions[i].laio_rv = ret;
completions[i].laio_errno = 0;
}
}
return (i);
}