3a65d6bd111a88a1b079fcd80e4ccfaf21358114
[akaros.git] / user / parlib / src / parlibmain.c
1 // Called from entry.S to get us going.
2
3 #include <parlib.h>
4 #include <stdlib.h>
5 #include <unistd.h>
6 #include <debug.h>
7 #include <hart.h>
8 #include <assert.h>
9
10 // call static destructors.
11 void parlib_dtors()
12 {
13         typedef void (*dtor)(void);
14         extern char __DTOR_LIST__[],__DTOR_END__[];
15         int ndtor = ((unsigned int)(__DTOR_END__-__DTOR_LIST__))/sizeof(void*);
16
17         // make sure only one thread actually runs the dtors
18         static int already_done = 0;
19         if(hart_swap(&already_done,1) == 1)
20                 return;
21
22         for(int i = 0; i < ndtor; i++)
23                 ((dtor*)__DTOR_LIST__)[i]();
24 }
25
26 // call static constructors.
27 void parlib_ctors()
28 {
29         typedef void (*ctor)(void);
30         extern char __CTOR_LIST__[],__CTOR_END__[];
31         int nctor = ((unsigned int)(__CTOR_END__-__CTOR_LIST__))/sizeof(void*);
32
33         for(int i = 0; i < nctor; i++)
34                 ((ctor*)__CTOR_LIST__)[nctor-i-1]();
35 }
36
37 // build argv from procinfo.argv_buf, which is a packed array
38 // of null-terminated strings, terminated by a final null character
39 char** parlib_build_argc_argv(int* argc)
40 {
41         char* buf = procinfo.argv_buf;
42         for(*argc = 0; *buf; (*argc)++)
43                 buf += strlen(buf)+1;
44
45         buf = procinfo.argv_buf;
46         char** argv = (char**)malloc(sizeof(char*)*(*argc+1));
47         for(int i = 0; i < *argc; i++)
48         {
49                 argv[i] = buf;
50                 buf += strlen(buf)+1;
51         }
52         argv[*argc] = 0;
53
54         return argv;
55 }
56
57 struct timeval timeval_start;
58
59 void parlibmain()
60 {
61         // only core 0 runs parlibmain, but if it yields then
62         // is given back, we don't want it to reinit things
63         static int initialized = 0;
64         if(initialized)
65         {
66                 hart_entry();
67                 hart_yield();
68         }
69         initialized = 1;
70
71         // get start time (for times)
72         if(gettimeofday(&timeval_start,NULL))
73                 timeval_start.tv_sec = timeval_start.tv_usec = 0;
74
75         // call static destructors
76         parlib_ctors();
77
78         // call static destructors on exit
79         atexit(&parlib_dtors);
80
81         // set up argc/argv
82         int argc;
83         char** argv = parlib_build_argc_argv(&argc);
84
85         // call user main routine
86         extern int main(int argc, char * NTS * COUNT(argc) NT argv);
87         int r = main(argc,argv);
88
89         // here I'd free(argv), but since we're exiting, it doesn't matter...
90
91         // exit gracefully
92         exit(r);
93 }
94