seq counters to protect vcoremap changes
[akaros.git] / kern / include / ros / procinfo.h
1 /* See COPYRIGHT for copyright information. */
2
3 #ifndef ROS_PROCINFO_H
4 #define ROS_PROCINFO_H
5
6 #include <ros/memlayout.h>
7 #include <ros/common.h>
8 #include <ros/atomic.h>
9 #include <ros/arch/arch.h>
10
11 #define PROCINFO_MAX_ARGP 32
12 #define PROCINFO_ARGBUF_SIZE 3072
13
14
15 /* Not necessary to expose all of this, but it doesn't hurt, and is convenient
16  * for the kernel. */
17 struct vcore {
18         uint32_t                        pcoreid;
19         bool                            valid;
20         bool                            preempt_served;
21         uint64_t                        preempt_pending;
22         struct trapframe        *tf_to_run;
23 };
24
25 struct pcore {
26         uint32_t                        vcoreid;
27         bool                            valid;
28 };
29
30 typedef struct procinfo {
31         pid_t pid;
32         pid_t ppid;
33         size_t max_harts;
34         uint64_t tsc_freq;
35         void* heap_bottom;
36         char* argp[PROCINFO_MAX_ARGP];
37         char argbuf[PROCINFO_ARGBUF_SIZE];
38         /* glibc relies on stuff above this point.  if you change it, you need to
39          * rebuild glibc. */
40         struct vcore            vcoremap[MAX_NUM_CPUS];
41         uint32_t                        num_vcores;
42         struct pcore            pcoremap[MAX_NUM_CPUS];
43         seq_ctr_t                       coremap_seqctr;
44 } procinfo_t;
45 #define PROCINFO_NUM_PAGES  ((sizeof(procinfo_t)-1)/PGSIZE + 1) 
46
47 static int
48 procinfo_pack_args(procinfo_t* p, char* const* argv, char* const* envp)
49 {
50         int nargv = 0, nenvp = 0;
51         if(argv) while(argv[nargv]) nargv++;
52         if(envp) while(envp[nenvp]) nenvp++;
53
54         if(nargv+nenvp+2 > PROCINFO_MAX_ARGP)
55                 return -1;
56
57         int pos = 0;
58         for(int i = 0; i < nargv; i++)
59         {
60                 int len = strlen(argv[i])+1;
61                 if(pos+len > PROCINFO_ARGBUF_SIZE)
62                         return -1;
63                 p->argp[i] = ((procinfo_t*)UINFO)->argbuf+pos;
64                 memcpy(p->argbuf+pos,argv[i],len);
65                 pos += len;
66         }
67         p->argp[nargv] = 0;
68
69         for(int i = 0; i < nenvp; i++)
70         {
71                 int len = strlen(envp[i])+1;
72                 if(pos+len > PROCINFO_ARGBUF_SIZE)
73                         return -1;
74                 p->argp[nargv+1+i] = ((procinfo_t*)UINFO)->argbuf+pos;
75                 memcpy(p->argbuf+pos,envp[i],len);
76                 pos += len;
77         }
78         p->argp[nargv+nenvp+1] = 0;
79         
80         return 0;
81 }
82
83 // this is how user programs access the procinfo page
84 #ifndef ROS_KERNEL
85 # define __procinfo (*(procinfo_t*)UINFO)
86 #endif
87
88 #endif // !ROS_PROCDATA_H