Subversion Repositories HelenOS

Rev

Rev 2877 | Rev 2880 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2877 Rev 2878
1
/** @addtogroup sctrace
1
/** @addtogroup sctrace
2
 * @{
2
 * @{
3
 */
3
 */
4
/** @file
4
/** @file
5
 */
5
 */
6
 
6
 
7
#include <stdio.h>
7
#include <stdio.h>
-
 
8
#include <stdlib.h>
8
#include <unistd.h>
9
#include <unistd.h>
9
#include <syscall.h>
10
#include <syscall.h>
10
#include <ipc/ipc.h>
11
#include <ipc/ipc.h>
11
#include <fibril.h>
12
#include <fibril.h>
12
#include <errno.h>
13
#include <errno.h>
13
#include <udebug.h>
14
#include <udebug.h>
14
#include <async.h>
15
#include <async.h>
15
 
16
 
-
 
17
#include "proto.h"
-
 
18
#include <ipc/services.h>
-
 
19
 
16
#include "syscalls.h"
20
#include "syscalls.h"
17
#include "ipcp.h"
21
#include "ipcp.h"
18
#include "errors.h"
22
#include "errors.h"
19
#include "debug_api.h"
23
#include "debug_api.h"
20
 
24
 
21
#define THBUF_SIZE 64
25
#define THBUF_SIZE 64
22
unsigned thread_hash_buf[THBUF_SIZE];
26
unsigned thread_hash_buf[THBUF_SIZE];
23
unsigned n_threads;
27
unsigned n_threads;
24
 
28
 
25
int next_thread_id;
29
int next_thread_id;
26
 
30
 
27
int phoneid;
31
int phoneid;
28
int abort_trace;
32
int abort_trace;
29
 
33
 
30
void thread_trace_start(unsigned thread_hash);
34
void thread_trace_start(unsigned thread_hash);
31
 
35
 
32
 
36
 
33
int task_connect(int taskid)
37
int task_connect(int taskid)
34
{
38
{
35
    int rc;
39
    int rc;
36
 
40
 
37
    printf("ipc_connect_task(%d)...\n", taskid);
41
    printf("ipc_connect_task(%d)...\n", taskid);
38
    rc = ipc_connect_kbox(taskid);
42
    rc = ipc_connect_kbox(taskid);
39
    printf("-> %d\n", rc);
43
    printf("-> %d\n", rc);
40
    phoneid = rc;
44
    phoneid = rc;
41
    if (rc < 0) return rc;
45
    if (rc < 0) return rc;
42
 
46
 
43
    printf("debug_begin()\n");
47
    printf("debug_begin()\n");
44
    rc = debug_begin(phoneid);
48
    rc = debug_begin(phoneid);
45
    printf("-> %d\n", rc);
49
    printf("-> %d\n", rc);
46
    if (rc < 0) return rc;
50
    if (rc < 0) return rc;
47
 
51
 
48
    return 0;
52
    return 0;
49
}
53
}
50
 
54
 
51
int get_thread_list(void)
55
int get_thread_list(void)
52
{
56
{
53
    int rc;
57
    int rc;
54
    int tb_copied;
58
    int tb_copied;
55
    int tb_needed;
59
    int tb_needed;
56
    int i;
60
    int i;
57
 
61
 
58
 
62
 
59
    printf("send IPC_M_DEBUG_THREAD_READ message\n");
63
    printf("send IPC_M_DEBUG_THREAD_READ message\n");
60
    rc = debug_thread_read(phoneid, (unsigned)thread_hash_buf,
64
    rc = debug_thread_read(phoneid, (unsigned)thread_hash_buf,
61
        THBUF_SIZE*sizeof(unsigned), &tb_copied, &tb_needed);
65
        THBUF_SIZE*sizeof(unsigned), &tb_copied, &tb_needed);
62
    printf("-> %d\n", rc);
66
    printf("-> %d\n", rc);
63
    if (rc < 0) return rc;
67
    if (rc < 0) return rc;
64
 
68
 
65
    n_threads = tb_copied / sizeof(unsigned);
69
    n_threads = tb_copied / sizeof(unsigned);
66
 
70
 
67
    printf("thread IDs:");
71
    printf("thread IDs:");
68
    for (i=0; i<n_threads; i++) {
72
    for (i=0; i<n_threads; i++) {
69
        printf(" %u", thread_hash_buf[i]);
73
        printf(" %u", thread_hash_buf[i]);
70
    }
74
    }
71
    printf("\ntotal of %u threads\n", tb_needed/sizeof(unsigned));
75
    printf("\ntotal of %u threads\n", tb_needed/sizeof(unsigned));
72
 
76
 
73
    return 0;
77
    return 0;
74
}
78
}
75
 
79
 
76
void print_sc_retval(int retval, rv_type_t rv_type)
80
void print_sc_retval(int retval, rv_type_t rv_type)
77
{
81
{
78
    printf (" -> ");
82
    printf (" -> ");
79
    if (rv_type == RV_INTEGER) {
83
    if (rv_type == RV_INTEGER) {
80
        printf("%d", retval);
84
        printf("%d", retval);
81
    } else if (rv_type == RV_HASH) {
85
    } else if (rv_type == RV_HASH) {
82
        printf("0x%08x", retval);
86
        printf("0x%08x", retval);
83
    } else if (rv_type == RV_ERRNO) {
87
    } else if (rv_type == RV_ERRNO) {
84
        if (retval >= -15 && retval <= 0) {
88
        if (retval >= -15 && retval <= 0) {
85
            printf("%d %s (%s)", retval,
89
            printf("%d %s (%s)", retval,
86
                err_desc[retval].name,
90
                err_desc[retval].name,
87
                err_desc[retval].desc);
91
                err_desc[retval].desc);
88
        } else {
92
        } else {
89
            printf("%d", retval);
93
            printf("%d", retval);
90
        }
94
        }
91
    } else if (rv_type == RV_INT_ERRNO) {
95
    } else if (rv_type == RV_INT_ERRNO) {
92
        if (retval >= -15 && retval < 0) {
96
        if (retval >= -15 && retval < 0) {
93
            printf("%d %s (%s)", retval,
97
            printf("%d %s (%s)", retval,
94
                err_desc[retval].name,
98
                err_desc[retval].name,
95
                err_desc[retval].desc);
99
                err_desc[retval].desc);
96
        } else {
100
        } else {
97
            printf("%d", retval);
101
            printf("%d", retval);
98
        }
102
        }
99
    }
103
    }
100
    putchar('\n');
104
    putchar('\n');
101
}
105
}
102
 
106
 
103
void print_sc_args(unsigned *sc_args, int n)
107
void print_sc_args(unsigned *sc_args, int n)
104
{
108
{
105
    int i;
109
    int i;
106
 
110
 
107
    putchar('(');
111
    putchar('(');
108
    if (n > 0) printf("%d", sc_args[0]);
112
    if (n > 0) printf("%d", sc_args[0]);
109
    for (i=1; i<n; i++) {
113
    for (i=1; i<n; i++) {
110
        printf(", %d", sc_args[i]);
114
        printf(", %d", sc_args[i]);
111
    }
115
    }
112
    putchar(')');
116
    putchar(')');
113
}
117
}
114
 
118
 
115
void sc_ipc_call_async_fast(unsigned *sc_args, int sc_rc)
119
void sc_ipc_call_async_fast(unsigned *sc_args, int sc_rc)
116
{
120
{
117
    ipc_call_t call;
121
    ipc_call_t call;
118
    int phoneid;
122
    int phoneid;
119
   
123
   
120
    if (sc_rc == IPC_CALLRET_FATAL || sc_rc == IPC_CALLRET_TEMPORARY)
124
    if (sc_rc == IPC_CALLRET_FATAL || sc_rc == IPC_CALLRET_TEMPORARY)
121
        return;
125
        return;
122
 
126
 
123
    phoneid = sc_args[0];
127
    phoneid = sc_args[0];
124
 
128
 
125
    IPC_SET_METHOD(call, sc_args[1]);
129
    IPC_SET_METHOD(call, sc_args[1]);
126
    IPC_SET_ARG1(call, sc_args[2]);
130
    IPC_SET_ARG1(call, sc_args[2]);
127
    IPC_SET_ARG2(call, sc_args[3]);
131
    IPC_SET_ARG2(call, sc_args[3]);
128
    IPC_SET_ARG3(call, sc_args[4]);
132
    IPC_SET_ARG3(call, sc_args[4]);
129
    IPC_SET_ARG4(call, sc_args[5]);
133
    IPC_SET_ARG4(call, sc_args[5]);
130
    IPC_SET_ARG5(call, 0);
134
    IPC_SET_ARG5(call, 0);
131
 
135
 
132
    ipcp_call_out(phoneid, &call, sc_rc);
136
    ipcp_call_out(phoneid, &call, sc_rc);
133
}
137
}
134
 
138
 
135
void sc_ipc_call_async_slow(unsigned *sc_args, int sc_rc)
139
void sc_ipc_call_async_slow(unsigned *sc_args, int sc_rc)
136
{
140
{
137
    ipc_call_t call;
141
    ipc_call_t call;
138
    int rc;
142
    int rc;
139
 
143
 
140
    if (sc_rc == IPC_CALLRET_FATAL || sc_rc == IPC_CALLRET_TEMPORARY)
144
    if (sc_rc == IPC_CALLRET_FATAL || sc_rc == IPC_CALLRET_TEMPORARY)
141
        return;
145
        return;
142
 
146
 
143
    memset(&call, 0, sizeof(call));
147
    memset(&call, 0, sizeof(call));
144
    rc = debug_mem_read(phoneid, &call.args, sc_args[1], sizeof(call.args));
148
    rc = debug_mem_read(phoneid, &call.args, sc_args[1], sizeof(call.args));
145
 
149
 
146
    if (rc >= 0) {
150
    if (rc >= 0) {
147
        ipcp_call_out(sc_args[0], &call, sc_rc);
151
        ipcp_call_out(sc_args[0], &call, sc_rc);
148
    }
152
    }
149
}
153
}
150
 
154
 
151
void sc_ipc_call_sync_fast(unsigned *sc_args)
155
void sc_ipc_call_sync_fast(unsigned *sc_args)
152
{
156
{
153
    ipc_call_t question, reply;
157
    ipc_call_t question, reply;
154
    int rc;
158
    int rc;
155
    int phoneidx;
159
    int phoneidx;
156
 
160
 
157
//  printf("sc_ipc_call_sync_fast()\n");
161
//  printf("sc_ipc_call_sync_fast()\n");
158
    phoneidx = sc_args[0];
162
    phoneidx = sc_args[0];
159
 
163
 
160
    IPC_SET_METHOD(question, sc_args[1]);
164
    IPC_SET_METHOD(question, sc_args[1]);
161
    IPC_SET_ARG1(question, sc_args[2]);
165
    IPC_SET_ARG1(question, sc_args[2]);
162
    IPC_SET_ARG2(question, sc_args[3]);
166
    IPC_SET_ARG2(question, sc_args[3]);
163
    IPC_SET_ARG3(question, sc_args[4]);
167
    IPC_SET_ARG3(question, sc_args[4]);
164
    IPC_SET_ARG4(question, 0);
168
    IPC_SET_ARG4(question, 0);
165
    IPC_SET_ARG5(question, 0);
169
    IPC_SET_ARG5(question, 0);
166
 
170
 
167
//  printf("memset\n");
171
//  printf("memset\n");
168
    memset(&reply, 0, sizeof(reply));
172
    memset(&reply, 0, sizeof(reply));
169
//  printf("debug_mem_read(phone=%d, buffer_ptr=%u, src_addr=%d, n=%d\n",
173
//  printf("debug_mem_read(phone=%d, buffer_ptr=%u, src_addr=%d, n=%d\n",
170
//      phoneid, &reply.args, sc_args[5], sizeof(reply.args));
174
//      phoneid, &reply.args, sc_args[5], sizeof(reply.args));
171
    rc = debug_mem_read(phoneid, &reply.args, sc_args[5], sizeof(reply.args));
175
    rc = debug_mem_read(phoneid, &reply.args, sc_args[5], sizeof(reply.args));
172
//  printf("dmr->%d\n", rc);
176
//  printf("dmr->%d\n", rc);
173
    if (rc < 0) return;
177
    if (rc < 0) return;
174
 
178
 
175
//  printf("call ipc_call_sync\n");
179
//  printf("call ipc_call_sync\n");
176
    ipcp_call_sync(phoneidx, &question, &reply);
180
    ipcp_call_sync(phoneidx, &question, &reply);
177
}
181
}
178
 
182
 
179
void sc_ipc_call_sync_slow(unsigned *sc_args)
183
void sc_ipc_call_sync_slow(unsigned *sc_args)
180
{
184
{
181
    ipc_call_t question, reply;
185
    ipc_call_t question, reply;
182
    int rc;
186
    int rc;
183
 
187
 
184
    memset(&question, 0, sizeof(question));
188
    memset(&question, 0, sizeof(question));
185
    rc = debug_mem_read(phoneid, &question.args, sc_args[1], sizeof(question.args));
189
    rc = debug_mem_read(phoneid, &question.args, sc_args[1], sizeof(question.args));
186
    printf("dmr->%d\n", rc);
190
    printf("dmr->%d\n", rc);
187
    if (rc < 0) return;
191
    if (rc < 0) return;
188
 
192
 
189
    memset(&reply, 0, sizeof(reply));
193
    memset(&reply, 0, sizeof(reply));
190
    rc = debug_mem_read(phoneid, &reply.args, sc_args[2], sizeof(reply.args));
194
    rc = debug_mem_read(phoneid, &reply.args, sc_args[2], sizeof(reply.args));
191
    printf("dmr->%d\n", rc);
195
    printf("dmr->%d\n", rc);
192
    if (rc < 0) return;
196
    if (rc < 0) return;
193
 
197
 
194
    ipcp_call_sync(sc_args[0], &question, &reply);
198
    ipcp_call_sync(sc_args[0], &question, &reply);
195
}
199
}
196
 
200
 
197
void sc_ipc_wait(unsigned *sc_args, int sc_rc)
201
void sc_ipc_wait(unsigned *sc_args, int sc_rc)
198
{
202
{
199
    ipc_call_t call;
203
    ipc_call_t call;
200
    int rc;
204
    int rc;
201
 
205
 
202
    if (sc_rc == 0) return 0;
206
    if (sc_rc == 0) return 0;
203
 
207
 
204
    memset(&call, 0, sizeof(call));
208
    memset(&call, 0, sizeof(call));
205
    rc = debug_mem_read(phoneid, &call, sc_args[0], sizeof(call));
209
    rc = debug_mem_read(phoneid, &call, sc_args[0], sizeof(call));
206
//  printf("debug_mem_read(phone %d, dest %d, app-mem src %d, size %d -> %d\n",
210
//  printf("debug_mem_read(phone %d, dest %d, app-mem src %d, size %d -> %d\n",
207
//      phoneid, (int)&call, sc_args[0], sizeof(call), rc);
211
//      phoneid, (int)&call, sc_args[0], sizeof(call), rc);
208
 
212
 
209
    if (rc >= 0) {
213
    if (rc >= 0) {
210
        ipcp_call_in(&call, sc_rc);
214
        ipcp_call_in(&call, sc_rc);
211
    }
215
    }
212
}
216
}
213
 
217
 
214
void event_syscall(unsigned thread_id, unsigned thread_hash,  unsigned sc_id, int sc_rc)
218
void event_syscall(unsigned thread_id, unsigned thread_hash,  unsigned sc_id, int sc_rc)
215
{
219
{
216
    unsigned sc_args[6];
220
    unsigned sc_args[6];
217
    int rv_type;
221
    int rv_type;
218
    int rc;
222
    int rc;
219
 
223
 
220
    /* Read syscall arguments */
224
    /* Read syscall arguments */
221
    rc = debug_args_read(phoneid, thread_hash, sc_args);
225
    rc = debug_args_read(phoneid, thread_hash, sc_args);
222
 
226
 
223
    async_serialize_start();
227
    async_serialize_start();
224
 
228
 
225
//  printf("[%d] ", thread_id);
229
//  printf("[%d] ", thread_id);
226
 
230
 
227
    if (rc < 0) {
231
    if (rc < 0) {
228
        printf("error\n");
232
        printf("error\n");
229
        async_serialize_end();
233
        async_serialize_end();
230
        return;
234
        return;
231
    }
235
    }
232
 
236
 
233
    /* Print syscall name, id and arguments */
237
    /* Print syscall name, id and arguments */
234
    printf("%s", syscall_desc[sc_id].name);
238
    printf("%s", syscall_desc[sc_id].name);
235
    print_sc_args(sc_args, syscall_desc[sc_id].n_args);
239
    print_sc_args(sc_args, syscall_desc[sc_id].n_args);
236
    rv_type = syscall_desc[sc_id].rv_type;
240
    rv_type = syscall_desc[sc_id].rv_type;
237
    print_sc_retval(sc_rc, rv_type);
241
    print_sc_retval(sc_rc, rv_type);
238
 
242
 
239
    switch (sc_id) {
243
    switch (sc_id) {
240
    case SYS_IPC_CALL_ASYNC_FAST:
244
    case SYS_IPC_CALL_ASYNC_FAST:
241
        sc_ipc_call_async_fast(sc_args, sc_rc);
245
        sc_ipc_call_async_fast(sc_args, sc_rc);
242
        break;
246
        break;
243
    case SYS_IPC_CALL_ASYNC_SLOW:
247
    case SYS_IPC_CALL_ASYNC_SLOW:
244
        sc_ipc_call_async_slow(sc_args, sc_rc);
248
        sc_ipc_call_async_slow(sc_args, sc_rc);
245
        break;
249
        break;
246
    case SYS_IPC_CALL_SYNC_FAST:
250
    case SYS_IPC_CALL_SYNC_FAST:
247
        sc_ipc_call_sync_fast(sc_args);
251
        sc_ipc_call_sync_fast(sc_args);
248
        break;
252
        break;
249
    case SYS_IPC_CALL_SYNC_SLOW:
253
    case SYS_IPC_CALL_SYNC_SLOW:
250
        sc_ipc_call_sync_slow(sc_args);
254
        sc_ipc_call_sync_slow(sc_args);
251
        break;
255
        break;
252
    case SYS_IPC_WAIT:
256
    case SYS_IPC_WAIT:
253
        sc_ipc_wait(sc_args, sc_rc);
257
        sc_ipc_wait(sc_args, sc_rc);
254
        break;
258
        break;
255
    default:
259
    default:
256
        break;
260
        break;
257
    }
261
    }
258
 
262
 
259
    async_serialize_end();
263
    async_serialize_end();
260
}
264
}
261
 
265
 
262
void event_new_thread(unsigned hash)
266
void event_new_thread(unsigned hash)
263
{
267
{
264
    async_serialize_start();
268
    async_serialize_start();
265
    printf("new thread, hash 0x%x\n", hash);
269
    printf("new thread, hash 0x%x\n", hash);
266
    async_serialize_end();
270
    async_serialize_end();
267
 
271
 
268
    thread_trace_start(hash);
272
    thread_trace_start(hash);
269
}
273
}
270
 
274
 
271
void trace_loop(void *thread_hash_arg)
275
void trace_loop(void *thread_hash_arg)
272
{
276
{
273
    int rc;
277
    int rc;
274
    unsigned ev_type;
278
    unsigned ev_type;
275
    unsigned thread_hash;
279
    unsigned thread_hash;
276
    unsigned thread_id;
280
    unsigned thread_id;
277
    unsigned val0, val1;
281
    unsigned val0, val1;
278
 
282
 
279
    thread_hash = (unsigned)thread_hash_arg;
283
    thread_hash = (unsigned)thread_hash_arg;
280
    thread_id = next_thread_id++;
284
    thread_id = next_thread_id++;
281
 
285
 
282
    printf("trace_loop(%d)\n", thread_id); 
286
    printf("trace_loop(%d)\n", thread_id); 
283
 
287
 
284
    while (!abort_trace) {
288
    while (!abort_trace) {
285
 
289
 
286
        /* Run thread until an event occurs */
290
        /* Run thread until an event occurs */
287
        rc = debug_go(phoneid, thread_hash,
291
        rc = debug_go(phoneid, thread_hash,
288
            &ev_type, &val0, &val1);
292
            &ev_type, &val0, &val1);
289
 
293
 
290
//      printf("rc = %d, ev_type=%d\n", rc, ev_type);
294
//      printf("rc = %d, ev_type=%d\n", rc, ev_type);
291
        if (ev_type == UDEBUG_EVENT_FINISHED) {
295
        if (ev_type == UDEBUG_EVENT_FINISHED) {
292
            printf("thread %u debugging finished\n", thread_id);
296
            printf("thread %u debugging finished\n", thread_id);
293
            break;
297
            break;
294
        }
298
        }
295
 
299
 
296
        if (rc >= 0) {
300
        if (rc >= 0) {
297
            switch (ev_type) {
301
            switch (ev_type) {
298
            case UDEBUG_EVENT_SYSCALL:
302
            case UDEBUG_EVENT_SYSCALL:
299
                event_syscall(thread_id, thread_hash, val0, (int)val1);
303
                event_syscall(thread_id, thread_hash, val0, (int)val1);
300
                break;
304
                break;
301
            case UDEBUG_EVENT_NEW_THREAD:
305
            case UDEBUG_EVENT_NEW_THREAD:
302
                event_new_thread(val0);
306
                event_new_thread(val0);
303
                break;
307
                break;
304
            default:
308
            default:
305
                printf("unknown event type %d\n", ev_type);
309
                printf("unknown event type %d\n", ev_type);
306
                break;
310
                break;
307
            }
311
            }
308
        }
312
        }
309
 
313
 
310
    }
314
    }
311
 
315
 
312
    printf("trace_loop(%d) exiting\n", thread_id);
316
    printf("trace_loop(%d) exiting\n", thread_id);
313
}
317
}
314
 
318
 
315
void thread_trace_start(unsigned thread_hash)
319
void thread_trace_start(unsigned thread_hash)
316
{
320
{
317
    fid_t fid;
321
    fid_t fid;
318
 
322
 
319
    fid = fibril_create(trace_loop, (void *)thread_hash);
323
    fid = fibril_create(trace_loop, (void *)thread_hash);
320
    if (fid == 0) {
324
    if (fid == 0) {
321
        printf("Warning: Failed creating fibril\n");
325
        printf("Warning: Failed creating fibril\n");
322
    }
326
    }
323
    fibril_add_ready(fid);
327
    fibril_add_ready(fid);
324
}
328
}
325
 
329
 
326
void trace_active_task(void)
330
void trace_active_task(void)
327
{
331
{
328
    int taskid;
332
    int taskid;
329
    int i;
333
    int i;
330
    int rc;
334
    int rc;
331
 
335
 
332
    printf("Syscall Tracer\n");
336
    printf("Syscall Tracer\n");
333
    printf("Press 'c' to connect\n");
337
    printf("Press 'c' to connect\n");
334
    while ((i = getchar()) != 'c')
338
    while ((i = getchar()) != 'c')
335
        putchar(i);
339
        putchar(i);
336
 
340
 
337
    taskid = 14;
341
    taskid = 14;
338
    rc = task_connect(taskid);
342
    rc = task_connect(taskid);
339
    if (rc < 0) {
343
    if (rc < 0) {
340
        printf("Failed to connect to task %d\n", taskid);
344
        printf("Failed to connect to task %d\n", taskid);
341
        return;
345
        return;
342
    }
346
    }
343
 
347
 
344
    printf("Connected to task %d\n", taskid);
348
    printf("Connected to task %d\n", taskid);
345
 
349
 
346
    ipcp_init();
350
    ipcp_init();
347
 
351
 
348
    rc = get_thread_list();
352
    rc = get_thread_list();
349
    if (rc < 0) {
353
    if (rc < 0) {
350
        printf("Failed to get thread list (error %d)\n", rc);
354
        printf("Failed to get thread list (error %d)\n", rc);
351
        return;
355
        return;
352
    }
356
    }
353
 
357
 
354
    abort_trace = 0;
358
    abort_trace = 0;
355
 
359
 
356
    for (i = 0; i < n_threads; i++) {
360
    for (i = 0; i < n_threads; i++) {
357
        thread_trace_start(thread_hash_buf[i]);
361
        thread_trace_start(thread_hash_buf[i]);
358
    }
362
    }
359
 
363
 
360
    getchar();
364
    getchar();
361
 
365
 
362
    printf("terminate debugging session...\n");
366
    printf("terminate debugging session...\n");
363
    abort_trace = 1;
367
    abort_trace = 1;
364
    debug_end(phoneid);
368
    debug_end(phoneid);
365
    ipc_hangup(phoneid);
369
    ipc_hangup(phoneid);
366
 
370
 
367
    ipcp_cleanup();
371
    ipcp_cleanup();
368
 
372
 
369
    printf("done\n");
373
    printf("done\n");
370
    return;
374
    return;
371
}
375
}
372
 
376
 
373
int main(void)
377
static void main_init(void)
374
{
378
{
-
 
379
    proto_t *p;
-
 
380
 
375
    next_thread_id = 1;
381
    next_thread_id = 1;
376
 
382
 
-
 
383
    proto_init();
-
 
384
 
-
 
385
    p = malloc(sizeof(proto_t));
-
 
386
    p->name = "vfs";
-
 
387
    proto_register(SERVICE_VFS, p);
-
 
388
}
-
 
389
 
-
 
390
int main(void)
-
 
391
{
-
 
392
    main_init();
-
 
393
 
377
    while (1) {
394
    while (1) {
378
        trace_active_task();
395
        trace_active_task();
379
    }
396
    }
380
}
397
}
381
 
398
 
382
/** @}
399
/** @}
383
 */
400
 */
384
 
401