forked from torvalds/linux
/
dce_host.c
309 lines (268 loc) · 6.81 KB
/
dce_host.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
// Basic headers for any host
// Contains host operation and system \
// call interface
#include <lkl_host.h>
#include <lkl.h>
// Some header will get replace with \
// Dce version
#include <pthread.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <signal.h>
#include <assert.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <stdint.h>
#include <sys/uio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/syscall.h>
#include <poll.h>
#include "iomem.h"
#include "jmp_buf.h"
// Referred from posix-host.c
//TODO: map error number to corresponding \
// error message if possible.
static int warn_pthread (int ret, char *str_exp)
{
if (ret > 0)
lkl_printf ("%s", str_exp);
return ret;
}
#define WARN_DCE_PTHREAD warn_pthread (exp)
static void print (const char *str, int len)
{
ssize_t ret __attribute__((unused));
// TODO:Need FD as first parameter
ret = dce_write (0, str, len)
}
static void panic (void)
{
// Let DCE handle this.
// Add dce_panic, find correct header in DCE
return;
}
// TODO: Need to decide how to SEMAPHORES should be handle in DCE
static struct lkl_sem* sem_alloc (int count)
{
return NULL;
}
static void sem_free (struct lkl_sem *sem)
{
return;
}
static void sem_up (struct lkl_sem *sem)
{
return;
}
static void sem_down (struct lkl_sem *sem)
{
return;
}
// TODO: Need to decide how to SEMAPHORES should be handle in DCE
static struct lkl_mutex *mutex_alloc (int recursive)
{
return NULL;
}
static void mutex_free (struct lkl_mutex *mutex)
{
return;
}
static void mutex_lock (struct lkl_mutex *mutex)
{
return;
}
static void mutex_unlock (struct lkl_mutex *mutex)
{
return;
}
static lkl_thread_t thread_create (void (*fn)(void *), void *arg)
{
// TODO: is warn message set by DCE.
pthread_t thread;
//TODO: might need to redefine; because it seems DCE pthread_create \
// returns zero only no error number.
if (WARN_DCE_PTHREAD(dce_pthread_create (&thread, NULL, (void* (*)(void *))fn, arg)))
return 0;
else
return (lkl_thread_t) thread;
}
static void thread_detach (void)
{
WARN_DCE_PTHREAD (dce_pthread_detach (dce_pthread_self ()))
}
//TODO: verify any argument is need rather NULL.
static void thread_exit (void)
{
dce_pthread_exit (NULL);
}
static int thread_join (lkl_thread_t tid)
{
if (WARN_DCE_PTHREAD (dce_pthread_join ((pthread_t) tid, NULL)))
return -1;
else
return 0;
}
static lkl_thread_t thread_self (void)
{
return (lkl_thread_t) dce_pthread_self ()
}
// Note: DCE uses NATIVE version of this function.
// For now let this function handle by original \
// pthread library.
// TODO: Check, any room to add this function in DCE (dce-pthread.cc).
static int thread_equal (lkl_thread_t a, lkl_thread_t b)
{
return pthread_equal ((pthread_t)a, (pthread_t)b);
}
static struct lkl_tls_key *tls_alloc (void (*destructor)(void *))
{
// TODO: Why POSIX won't typecast to (lkl_tls_key *)
struct lkl_tls_key *ret = dce_malloc (sizeof (struct lkl_tls_key));
if (WARN_DCE_PTHREAD (dce_pthread_key_create (&ret->key, destructor)))
{
dce_free (ret);
return NULL;
}
return ret;
}
static void tls_free (struct lkl_tls_key *key)
{
WARN_DCE_PTHREAD (dce_pthread_key_delete (key->key));
dce_free (key);
}
static int tls_set (struct lkl_tls_key *key, void *data)
{
if (WARN_DCE_PTHREAD (dce_pthread_setspecific (key->key, data)));
return -1
return 0;
}
static void tls_get (struct lkl_tls_key *key)
{
return dce_pthread_getspecific (key->key);
}
static void* mem_alloc (unsigned long size)
{
return dce_malloc ((size_t) size)
}
// Standard and DCE free method doesn't \
// return any thing.
// TODO: What should be the return value here?
static void mem_free (void * ptr)
{
dce_free (ptr);
// for now success always
return 0;
}
static unsigned long long time (void)
{
struct timespace ts;
// TODO: check which clk id best suits in DCE
dce_clock_gettime (CLOCK_MONOTONIC, &ts);
return 1e9*ts.tv_sec + ts.tv_nsec;
}
static void* timer_alloc (void (*fn)(void *), void *arg)
{
int err;
timer_t timer;
struct sigevent se = {
.sigev_notify = SIGEV_THREAD,
.sigev_value = {
.sival_ptr = arg,
},
.sigev_notify_function = (void (*)(union sigval))fn;
};
err = dce_timer_create (CLOCK_REALTIME, &se, &timer);
if (err)
return NULL:
// TODO: why directly typecast into (void *)
return (void *)(long) timer;
}
static int timer_set_oneshot (void *timer, unsigned long delta)
{
timer_t timer = (timer_t)(long)_timer;
struct itimerspec ts = {
.it_value = {
.tv_sec = ns / 1000000000,
.tv_nsec = ns % 1000000000,
},
};
return dce_timer_settime(timer, 0, &ts, NULL);
}
// dce_timer_delete not found
// TODO: try to find workaround
static void timer_free (void *timer)
{
return;
}
// @ioremap - searches for an I/O memory region identified by addr and size and
// returns a pointer to the start of the address range that can be used by
// iomem_access
static void* ioremap (long addr, int size)
{
// As such not need;
// TODO:discuss and descibe some action
}
// @iomem_acess - reads or writes to and I/O memory region; addr must be in the
// * range returned by ioremap
static int iomem_access (const volatile void *addr, void *val, int size, int write)
{
// As such not need;
// TODO:discuss and descibe some action
}
static long gettid (void)
{
return (long) dce_pthread_self ();
}
// @jmp_buf_set - runs the give function and setups a jump back point by saving
// the context in the jump buffer; jmp_buf_longjmp can be called from the give
// function or any callee in that function to return back to the jump back
// point
static void jmp_buf_set (struct lkl_jmp_buf *jmpb, void (*f)(void))
{
// Seems relevant to dce, not sure how to handle;
return;
}
static void jmp_buf_longjmp (struct lkl_jmp_buf *jmpb, int val)
{
// Seems relevant to dce, not sure how to handle;
return;
}
struct lkl_host_operations lkl_host_ops = {
// TODO: verify the usage
const char *virtio_devices;
.print = print;
.panic = panic;
.lkl_sem = lkl_sem;
.sem_free = sem_free;
.sem_up = sem_up;
.sem_down = sem_down;
.lkl_mutex = lkl_mutex;
.mutex_free = mutex_free;
.mutex_lock = mutex_lock;
.mutex_unlock = mutex_unlock;
.thread_create = thread_create;
.thread_detach = thread_detach;
.thread_exit = thread_exit;
.thread_join = thread_join;
.thread_self = thread_self;
.thread_equal = thread_equal;
.tls_alloc = tls_alloc;
.tls_free = tls_free;
.tls_set = tls_set;
.tls_get = tls_get
.mem_alloc = mem_alloc;
.mem_free = mem_free;
.time = time;
.timer_alloc = timer_alloc;
.timer_set_oneshot = timer_set_oneshot;
.timer_free = timer_free;
.ioremap = ioremap;
.iomem_access = iomem_access
.gettid = gettid;
.jmp_buf_set = jmp_buf_set;
.jmp_buf_longjmp = jmp_buf_longjmp;
};