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