Add READ_ONCE and WRITE_ONCE (XCC)
[akaros.git] / kern / include / ros / procinfo.h
index d17be23..56bf7d9 100644 (file)
@@ -1,15 +1,18 @@
 /* See COPYRIGHT for copyright information. */
 
-#ifndef ROS_PROCINFO_H
-#define ROS_PROCINFO_H
+#pragma once
 
 #include <ros/memlayout.h>
 #include <ros/common.h>
 #include <ros/resource.h>
 #include <ros/atomic.h>
 #include <ros/arch/arch.h>
+#include <ros/cpu_feat.h>
 #include <string.h>
 
+/* Process creation flags */
+#define PROC_DUP_FGRP                  1
+
 #define PROCINFO_MAX_ARGP 32
 #define PROCINFO_ARGBUF_SIZE 3072
 
@@ -32,6 +35,10 @@ struct vcore {
        uint32_t                        nr_preempts_sent;       /* these two differ when a preempt*/
        uint32_t                        nr_preempts_done;       /* is in flight. */
        uint64_t                        preempt_pending;
+       /* A process can see cumulative runtime as of the last resume, and can also
+        * calculate runtime in this interval, by adding (ns - resume) + total. */
+       uint64_t                        resume_ticks;           /* TSC at resume time */
+       uint64_t                        total_ticks;            /* ticks up to last offlining */
 };
 
 struct pcore {
@@ -42,63 +49,42 @@ struct pcore {
 typedef struct procinfo {
        pid_t pid;
        pid_t ppid;
-       size_t max_vcores;
+       size_t max_vcores;      /* TODO: change to a uint32_t */
        uint64_t tsc_freq;
-       void* heap_bottom;
-       /* for traditional forks, these two need to be memcpy'd over: */
-       char* argp[PROCINFO_MAX_ARGP];
-       char argbuf[PROCINFO_ARGBUF_SIZE];
+       uint64_t timing_overhead;
+       uintptr_t program_end;
        /* glibc relies on stuff above this point.  if you change it, you need to
         * rebuild glibc. */
        bool is_mcp;                    /* is in multi mode */
        unsigned long           res_grant[MAX_NUM_RESOURCES];
-       struct vcore            vcoremap[MAX_NUM_CPUS];
+       struct vcore            vcoremap[MAX_NUM_CORES];
        uint32_t                        num_vcores;
-       struct pcore            pcoremap[MAX_NUM_CPUS];
+       struct pcore            pcoremap[MAX_NUM_CORES];
        seq_ctr_t                       coremap_seqctr;
 } procinfo_t;
-#define PROCINFO_NUM_PAGES  ((sizeof(procinfo_t)-1)/PGSIZE + 1)        
+#define PROCINFO_NUM_PAGES  ((sizeof(procinfo_t)-1)/PGSIZE + 1)
 
-static int
-procinfo_pack_args(procinfo_t* p, char* const* argv, char* const* envp)
-{
-       int nargv = 0, nenvp = 0;
-       if(argv) while(argv[nargv]) nargv++;
-       if(envp) while(envp[nenvp]) nenvp++;
-
-       if(nargv+nenvp+2 > PROCINFO_MAX_ARGP)
-               return -1;
-
-       int pos = 0;
-       int i;
-       for(i = 0; i < nargv; i++)
-       {
-               int len = strlen(argv[i])+1;
-               if(pos+len > PROCINFO_ARGBUF_SIZE)
-                       return -1;
-               p->argp[i] = ((procinfo_t*)UINFO)->argbuf+pos;
-               memcpy(p->argbuf+pos,argv[i],len);
-               pos += len;
-       }
-       p->argp[nargv] = 0;
-
-       for(i = 0; i < nenvp; i++)
-       {
-               int len = strlen(envp[i])+1;
-               if(pos+len > PROCINFO_ARGBUF_SIZE)
-                       return -1;
-               p->argp[nargv+1+i] = ((procinfo_t*)UINFO)->argbuf+pos;
-               memcpy(p->argbuf+pos,envp[i],len);
-               pos += len;
-       }
-       p->argp[nargv+nenvp+1] = 0;
-       
-       return 0;
-}
+/* We align this so that the kernel can easily allocate it in the BSS */
+struct proc_global_info {
+       unsigned long cpu_feats[__NR_CPU_FEAT_BITS];
+       uint64_t x86_default_xcr0;
+       uint64_t tsc_freq;
+       uint64_t tsc_overhead;
+       uint64_t bus_freq;
+       uint64_t walltime_ns_last;
+       uint64_t tsc_cycles_last;
+} __attribute__((aligned(PGSIZE)));
+#define PROCGINFO_NUM_PAGES  (sizeof(struct proc_global_info) / PGSIZE)
+
+#ifdef ROS_KERNEL
+
+/* defined in init.c */
+extern struct proc_global_info __proc_global_info;
+
+#else /* Userland */
 
-// this is how user programs access the procinfo page
-#ifndef ROS_KERNEL
-# define __procinfo (*(procinfo_t*)UINFO)
+#define __procinfo (*(procinfo_t*)UINFO)
+#define __proc_global_info (*(struct proc_global_info*)UGINFO)
 
 #include <ros/common.h>
 #include <ros/atomic.h>
@@ -113,11 +99,14 @@ static inline uint32_t __get_vcoreid_from_procinfo(void)
         * there is a 'memory barrier' between the IPI write and the seqctr write.
         * I think this is true. */
        uint32_t kpcoreid, kvcoreid;
+       extern long __ros_syscall_noerrno(unsigned int _num, long _a0, long _a1,
+                                         long _a2, long _a3, long _a4, long _a5);
+
        seq_ctr_t old_seq;
        do {
                cmb();
                old_seq = __procinfo.coremap_seqctr;
-               kpcoreid = __ros_syscall(SYS_getpcoreid, 0, 0, 0, 0, 0, 0, NULL);
+               kpcoreid = __ros_syscall_noerrno(SYS_getpcoreid, 0, 0, 0, 0, 0, 0);
                if (!__procinfo.pcoremap[kpcoreid].valid)
                        continue;
                kvcoreid = __procinfo.pcoremap[kpcoreid].vcoreid;
@@ -132,5 +121,3 @@ static inline uint32_t __get_vcoreid(void)
 }
 
 #endif /* ifndef ROS_KERNEL */
-
-#endif // !ROS_PROCDATA_H