Moves resource requests to procdata (XCC)
[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/resource.h>
9 #include <ros/atomic.h>
10 #include <ros/arch/arch.h>
11
12 #define PROCINFO_MAX_ARGP 32
13 #define PROCINFO_ARGBUF_SIZE 3072
14
15 #ifdef ROS_KERNEL
16 #include <sys/queue.h>
17 #endif /* ROS_KERNEL */
18
19 /* Not necessary to expose all of this, but it doesn't hurt, and is convenient
20  * for the kernel.  Need to do some acrobatics for the TAILQ_ENTRY. */
21 struct vcore;
22 struct vcore {
23 #ifdef ROS_KERNEL
24         TAILQ_ENTRY(vcore)      list;
25 #else /* userspace */
26         void                            *dummy_ptr1;
27         void                            *dummy_ptr2;
28 #endif /* ROS_KERNEL */
29         uint32_t                        pcoreid;
30         bool                            valid;
31         bool                            preempt_served;
32         uint64_t                        preempt_pending;
33 };
34
35 struct pcore {
36         uint32_t                        vcoreid;
37         bool                            valid;
38 };
39
40 typedef struct procinfo {
41         pid_t pid;
42         pid_t ppid;
43         size_t max_vcores;
44         uint64_t tsc_freq;
45         void* heap_bottom;
46         /* for traditional forks, these two need to be memcpy'd over: */
47         char* argp[PROCINFO_MAX_ARGP];
48         char argbuf[PROCINFO_ARGBUF_SIZE];
49         /* glibc relies on stuff above this point.  if you change it, you need to
50          * rebuild glibc. */
51         bool is_mcp;                    /* is in multi mode */
52         unsigned long           res_grant[MAX_NUM_RESOURCES];
53         struct vcore            vcoremap[MAX_NUM_CPUS];
54         uint32_t                        num_vcores;
55         struct pcore            pcoremap[MAX_NUM_CPUS];
56         seq_ctr_t                       coremap_seqctr;
57 } procinfo_t;
58 #define PROCINFO_NUM_PAGES  ((sizeof(procinfo_t)-1)/PGSIZE + 1) 
59
60 static int
61 procinfo_pack_args(procinfo_t* p, char* const* argv, char* const* envp)
62 {
63         int nargv = 0, nenvp = 0;
64         if(argv) while(argv[nargv]) nargv++;
65         if(envp) while(envp[nenvp]) nenvp++;
66
67         if(nargv+nenvp+2 > PROCINFO_MAX_ARGP)
68                 return -1;
69
70         int pos = 0;
71         for(int i = 0; i < nargv; i++)
72         {
73                 int len = strlen(argv[i])+1;
74                 if(pos+len > PROCINFO_ARGBUF_SIZE)
75                         return -1;
76                 p->argp[i] = ((procinfo_t*)UINFO)->argbuf+pos;
77                 memcpy(p->argbuf+pos,argv[i],len);
78                 pos += len;
79         }
80         p->argp[nargv] = 0;
81
82         for(int i = 0; i < nenvp; i++)
83         {
84                 int len = strlen(envp[i])+1;
85                 if(pos+len > PROCINFO_ARGBUF_SIZE)
86                         return -1;
87                 p->argp[nargv+1+i] = ((procinfo_t*)UINFO)->argbuf+pos;
88                 memcpy(p->argbuf+pos,envp[i],len);
89                 pos += len;
90         }
91         p->argp[nargv+nenvp+1] = 0;
92         
93         return 0;
94 }
95
96 // this is how user programs access the procinfo page
97 #ifndef ROS_KERNEL
98 # define __procinfo (*(procinfo_t*)UINFO)
99 #endif
100
101 #endif // !ROS_PROCDATA_H