Add performance profiler for threads and system calls
This commit is contained in:
		
							parent
							
								
									a1e003ebdb
								
							
						
					
					
						commit
						74fad28938
					
				| @ -50,6 +50,8 @@ enclave { | |||||||
|          */ |          */ | ||||||
|         int occlum_ocall_exec_thread_async(int libos_tid); |         int occlum_ocall_exec_thread_async(int libos_tid); | ||||||
| 
 | 
 | ||||||
|  |         int occlum_ocall_thread_getcpuclock([out] struct timespec* ts) propagate_errno; | ||||||
|  | 
 | ||||||
|         void occlum_ocall_gettimeofday([out] struct timeval* tv); |         void occlum_ocall_gettimeofday([out] struct timeval* tv); | ||||||
|         void occlum_ocall_clock_gettime(clockid_t clockid, [out] struct timespec* ts); |         void occlum_ocall_clock_gettime(clockid_t clockid, [out] struct timespec* ts); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -86,4 +86,5 @@ use self::task::Task; | |||||||
| use super::*; | use super::*; | ||||||
| use fs::{File, FileRef, FileTable}; | use fs::{File, FileRef, FileTable}; | ||||||
| use misc::ResourceLimitsRef; | use misc::ResourceLimitsRef; | ||||||
|  | use time::GLOBAL_PROFILER; | ||||||
| use vm::ProcessVM; | use vm::ProcessVM; | ||||||
|  | |||||||
| @ -98,11 +98,25 @@ pub fn run_task(libos_tid: pid_t, host_tid: pid_t) -> Result<i32> { | |||||||
|         (pid, task) |         (pid, task) | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |     #[cfg(feature = "syscall_timing")] | ||||||
|  |     GLOBAL_PROFILER | ||||||
|  |         .lock() | ||||||
|  |         .unwrap() | ||||||
|  |         .thread_enter() | ||||||
|  |         .expect("unexpected error from profiler to enter thread"); | ||||||
|  | 
 | ||||||
|     unsafe { |     unsafe { | ||||||
|         // task may only be modified by this function; so no lock is needed
 |         // task may only be modified by this function; so no lock is needed
 | ||||||
|         do_run_task(task); |         do_run_task(task); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     #[cfg(feature = "syscall_timing")] | ||||||
|  |     GLOBAL_PROFILER | ||||||
|  |         .lock() | ||||||
|  |         .unwrap() | ||||||
|  |         .thread_exit() | ||||||
|  |         .expect("unexpected error from profiler to exit thread"); | ||||||
|  | 
 | ||||||
|     let (exit_status, parent_pid) = { |     let (exit_status, parent_pid) = { | ||||||
|         let mut process = new_process.lock().unwrap(); |         let mut process = new_process.lock().unwrap(); | ||||||
|         let parent = process.get_parent().lock().unwrap(); |         let parent = process.get_parent().lock().unwrap(); | ||||||
|  | |||||||
| @ -1,330 +0,0 @@ | |||||||
| //! Syscall numbers
 |  | ||||||
| 
 |  | ||||||
| pub const SYS_READ: u32 = 0; |  | ||||||
| pub const SYS_WRITE: u32 = 1; |  | ||||||
| pub const SYS_OPEN: u32 = 2; |  | ||||||
| pub const SYS_CLOSE: u32 = 3; |  | ||||||
| pub const SYS_STAT: u32 = 4; |  | ||||||
| pub const SYS_FSTAT: u32 = 5; |  | ||||||
| pub const SYS_LSTAT: u32 = 6; |  | ||||||
| pub const SYS_POLL: u32 = 7; |  | ||||||
| pub const SYS_LSEEK: u32 = 8; |  | ||||||
| pub const SYS_MMAP: u32 = 9; |  | ||||||
| pub const SYS_MPROTECT: u32 = 10; |  | ||||||
| pub const SYS_MUNMAP: u32 = 11; |  | ||||||
| pub const SYS_BRK: u32 = 12; |  | ||||||
| pub const SYS_RT_SIGACTION: u32 = 13; |  | ||||||
| pub const SYS_RT_SIGPROCMASK: u32 = 14; |  | ||||||
| pub const SYS_RT_SIGRETURN: u32 = 15; |  | ||||||
| pub const SYS_IOCTL: u32 = 16; |  | ||||||
| pub const SYS_PREAD64: u32 = 17; |  | ||||||
| pub const SYS_PWRITE64: u32 = 18; |  | ||||||
| pub const SYS_READV: u32 = 19; |  | ||||||
| pub const SYS_WRITEV: u32 = 20; |  | ||||||
| pub const SYS_ACCESS: u32 = 21; |  | ||||||
| pub const SYS_PIPE: u32 = 22; |  | ||||||
| pub const SYS_SELECT: u32 = 23; |  | ||||||
| pub const SYS_SCHED_YIELD: u32 = 24; |  | ||||||
| pub const SYS_MREMAP: u32 = 25; |  | ||||||
| pub const SYS_MSYNC: u32 = 26; |  | ||||||
| pub const SYS_MINCORE: u32 = 27; |  | ||||||
| pub const SYS_MADVISE: u32 = 28; |  | ||||||
| pub const SYS_SHMGET: u32 = 29; |  | ||||||
| pub const SYS_SHMAT: u32 = 30; |  | ||||||
| pub const SYS_SHMCTL: u32 = 31; |  | ||||||
| pub const SYS_DUP: u32 = 32; |  | ||||||
| pub const SYS_DUP2: u32 = 33; |  | ||||||
| pub const SYS_PAUSE: u32 = 34; |  | ||||||
| pub const SYS_NANOSLEEP: u32 = 35; |  | ||||||
| pub const SYS_GETITIMER: u32 = 36; |  | ||||||
| pub const SYS_ALARM: u32 = 37; |  | ||||||
| pub const SYS_SETITIMER: u32 = 38; |  | ||||||
| pub const SYS_GETPID: u32 = 39; |  | ||||||
| pub const SYS_SENDFILE: u32 = 40; |  | ||||||
| pub const SYS_SOCKET: u32 = 41; |  | ||||||
| pub const SYS_CONNECT: u32 = 42; |  | ||||||
| pub const SYS_ACCEPT: u32 = 43; |  | ||||||
| pub const SYS_SENDTO: u32 = 44; |  | ||||||
| pub const SYS_RECVFROM: u32 = 45; |  | ||||||
| pub const SYS_SENDMSG: u32 = 46; |  | ||||||
| pub const SYS_RECVMSG: u32 = 47; |  | ||||||
| pub const SYS_SHUTDOWN: u32 = 48; |  | ||||||
| pub const SYS_BIND: u32 = 49; |  | ||||||
| pub const SYS_LISTEN: u32 = 50; |  | ||||||
| pub const SYS_GETSOCKNAME: u32 = 51; |  | ||||||
| pub const SYS_GETPEERNAME: u32 = 52; |  | ||||||
| pub const SYS_SOCKETPAIR: u32 = 53; |  | ||||||
| pub const SYS_SETSOCKOPT: u32 = 54; |  | ||||||
| pub const SYS_GETSOCKOPT: u32 = 55; |  | ||||||
| pub const SYS_CLONE: u32 = 56; |  | ||||||
| pub const SYS_FORK: u32 = 57; |  | ||||||
| pub const SYS_VFORK: u32 = 58; |  | ||||||
| pub const SYS_EXECVE: u32 = 59; |  | ||||||
| pub const SYS_EXIT: u32 = 60; |  | ||||||
| pub const SYS_WAIT4: u32 = 61; |  | ||||||
| pub const SYS_KILL: u32 = 62; |  | ||||||
| pub const SYS_UNAME: u32 = 63; |  | ||||||
| pub const SYS_SEMGET: u32 = 64; |  | ||||||
| pub const SYS_SEMOP: u32 = 65; |  | ||||||
| pub const SYS_SEMCTL: u32 = 66; |  | ||||||
| pub const SYS_SHMDT: u32 = 67; |  | ||||||
| pub const SYS_MSGGET: u32 = 68; |  | ||||||
| pub const SYS_MSGSND: u32 = 69; |  | ||||||
| pub const SYS_MSGRCV: u32 = 70; |  | ||||||
| pub const SYS_MSGCTL: u32 = 71; |  | ||||||
| pub const SYS_FCNTL: u32 = 72; |  | ||||||
| pub const SYS_FLOCK: u32 = 73; |  | ||||||
| pub const SYS_FSYNC: u32 = 74; |  | ||||||
| pub const SYS_FDATASYNC: u32 = 75; |  | ||||||
| pub const SYS_TRUNCATE: u32 = 76; |  | ||||||
| pub const SYS_FTRUNCATE: u32 = 77; |  | ||||||
| pub const SYS_GETDENTS: u32 = 78; |  | ||||||
| pub const SYS_GETCWD: u32 = 79; |  | ||||||
| pub const SYS_CHDIR: u32 = 80; |  | ||||||
| pub const SYS_FCHDIR: u32 = 81; |  | ||||||
| pub const SYS_RENAME: u32 = 82; |  | ||||||
| pub const SYS_MKDIR: u32 = 83; |  | ||||||
| pub const SYS_RMDIR: u32 = 84; |  | ||||||
| pub const SYS_CREAT: u32 = 85; |  | ||||||
| pub const SYS_LINK: u32 = 86; |  | ||||||
| pub const SYS_UNLINK: u32 = 87; |  | ||||||
| pub const SYS_SYMLINK: u32 = 88; |  | ||||||
| pub const SYS_READLINK: u32 = 89; |  | ||||||
| pub const SYS_CHMOD: u32 = 90; |  | ||||||
| pub const SYS_FCHMOD: u32 = 91; |  | ||||||
| pub const SYS_CHOWN: u32 = 92; |  | ||||||
| pub const SYS_FCHOWN: u32 = 93; |  | ||||||
| pub const SYS_LCHOWN: u32 = 94; |  | ||||||
| pub const SYS_UMASK: u32 = 95; |  | ||||||
| pub const SYS_GETTIMEOFDAY: u32 = 96; |  | ||||||
| pub const SYS_GETRLIMIT: u32 = 97; |  | ||||||
| pub const SYS_GETRUSAGE: u32 = 98; |  | ||||||
| pub const SYS_SYSINFO: u32 = 99; |  | ||||||
| pub const SYS_TIMES: u32 = 100; |  | ||||||
| pub const SYS_PTRACE: u32 = 101; |  | ||||||
| pub const SYS_GETUID: u32 = 102; |  | ||||||
| pub const SYS_SYSLOG: u32 = 103; |  | ||||||
| pub const SYS_GETGID: u32 = 104; |  | ||||||
| pub const SYS_SETUID: u32 = 105; |  | ||||||
| pub const SYS_SETGID: u32 = 106; |  | ||||||
| pub const SYS_GETEUID: u32 = 107; |  | ||||||
| pub const SYS_GETEGID: u32 = 108; |  | ||||||
| pub const SYS_SETPGID: u32 = 109; |  | ||||||
| pub const SYS_GETPPID: u32 = 110; |  | ||||||
| pub const SYS_GETPGRP: u32 = 111; |  | ||||||
| pub const SYS_SETSID: u32 = 112; |  | ||||||
| pub const SYS_SETREUID: u32 = 113; |  | ||||||
| pub const SYS_SETREGID: u32 = 114; |  | ||||||
| pub const SYS_GETGROUPS: u32 = 115; |  | ||||||
| pub const SYS_SETGROUPS: u32 = 116; |  | ||||||
| pub const SYS_SETRESUID: u32 = 117; |  | ||||||
| pub const SYS_GETRESUID: u32 = 118; |  | ||||||
| pub const SYS_SETRESGID: u32 = 119; |  | ||||||
| pub const SYS_GETRESGID: u32 = 120; |  | ||||||
| pub const SYS_GETPGID: u32 = 121; |  | ||||||
| pub const SYS_SETFSUID: u32 = 122; |  | ||||||
| pub const SYS_SETFSGID: u32 = 123; |  | ||||||
| pub const SYS_GETSID: u32 = 124; |  | ||||||
| pub const SYS_CAPGET: u32 = 125; |  | ||||||
| pub const SYS_CAPSET: u32 = 126; |  | ||||||
| pub const SYS_RT_SIGPENDING: u32 = 127; |  | ||||||
| pub const SYS_RT_SIGTIMEDWAIT: u32 = 128; |  | ||||||
| pub const SYS_RT_SIGQUEUEINFO: u32 = 129; |  | ||||||
| pub const SYS_RT_SIGSUSPEND: u32 = 130; |  | ||||||
| pub const SYS_SIGALTSTACK: u32 = 131; |  | ||||||
| pub const SYS_UTIME: u32 = 132; |  | ||||||
| pub const SYS_MKNOD: u32 = 133; |  | ||||||
| pub const SYS_USELIB: u32 = 134; |  | ||||||
| pub const SYS_PERSONALITY: u32 = 135; |  | ||||||
| pub const SYS_USTAT: u32 = 136; |  | ||||||
| pub const SYS_STATFS: u32 = 137; |  | ||||||
| pub const SYS_FSTATFS: u32 = 138; |  | ||||||
| pub const SYS_SYSFS: u32 = 139; |  | ||||||
| pub const SYS_GETPRIORITY: u32 = 140; |  | ||||||
| pub const SYS_SETPRIORITY: u32 = 141; |  | ||||||
| pub const SYS_SCHED_SETPARAM: u32 = 142; |  | ||||||
| pub const SYS_SCHED_GETPARAM: u32 = 143; |  | ||||||
| pub const SYS_SCHED_SETSCHEDULER: u32 = 144; |  | ||||||
| pub const SYS_SCHED_GETSCHEDULER: u32 = 145; |  | ||||||
| pub const SYS_SCHED_GET_PRIORITY_MAX: u32 = 146; |  | ||||||
| pub const SYS_SCHED_GET_PRIORITY_MIN: u32 = 147; |  | ||||||
| pub const SYS_SCHED_RR_GET_INTERVAL: u32 = 148; |  | ||||||
| pub const SYS_MLOCK: u32 = 149; |  | ||||||
| pub const SYS_MUNLOCK: u32 = 150; |  | ||||||
| pub const SYS_MLOCKALL: u32 = 151; |  | ||||||
| pub const SYS_MUNLOCKALL: u32 = 152; |  | ||||||
| pub const SYS_VHANGUP: u32 = 153; |  | ||||||
| pub const SYS_MODIFY_LDT: u32 = 154; |  | ||||||
| pub const SYS_PIVOT_ROOT: u32 = 155; |  | ||||||
| pub const SYS__SYSCTL: u32 = 156; |  | ||||||
| pub const SYS_PRCTL: u32 = 157; |  | ||||||
| pub const SYS_ARCH_PRCTL: u32 = 158; |  | ||||||
| pub const SYS_ADJTIMEX: u32 = 159; |  | ||||||
| pub const SYS_SETRLIMIT: u32 = 160; |  | ||||||
| pub const SYS_CHROOT: u32 = 161; |  | ||||||
| pub const SYS_SYNC: u32 = 162; |  | ||||||
| pub const SYS_ACCT: u32 = 163; |  | ||||||
| pub const SYS_SETTIMEOFDAY: u32 = 164; |  | ||||||
| pub const SYS_MOUNT: u32 = 165; |  | ||||||
| pub const SYS_UMOUNT2: u32 = 166; |  | ||||||
| pub const SYS_SWAPON: u32 = 167; |  | ||||||
| pub const SYS_SWAPOFF: u32 = 168; |  | ||||||
| pub const SYS_REBOOT: u32 = 169; |  | ||||||
| pub const SYS_SETHOSTNAME: u32 = 170; |  | ||||||
| pub const SYS_SETDOMAINNAME: u32 = 171; |  | ||||||
| pub const SYS_IOPL: u32 = 172; |  | ||||||
| pub const SYS_IOPERM: u32 = 173; |  | ||||||
| pub const SYS_CREATE_MODULE: u32 = 174; |  | ||||||
| pub const SYS_INIT_MODULE: u32 = 175; |  | ||||||
| pub const SYS_DELETE_MODULE: u32 = 176; |  | ||||||
| pub const SYS_GET_KERNEL_SYMS: u32 = 177; |  | ||||||
| pub const SYS_QUERY_MODULE: u32 = 178; |  | ||||||
| pub const SYS_QUOTACTL: u32 = 179; |  | ||||||
| pub const SYS_NFSSERVCTL: u32 = 180; |  | ||||||
| pub const SYS_GETPMSG: u32 = 181; |  | ||||||
| pub const SYS_PUTPMSG: u32 = 182; |  | ||||||
| pub const SYS_AFS_SYSCALL: u32 = 183; |  | ||||||
| pub const SYS_TUXCALL: u32 = 184; |  | ||||||
| pub const SYS_SECURITY: u32 = 185; |  | ||||||
| pub const SYS_GETTID: u32 = 186; |  | ||||||
| pub const SYS_READAHEAD: u32 = 187; |  | ||||||
| pub const SYS_SETXATTR: u32 = 188; |  | ||||||
| pub const SYS_LSETXATTR: u32 = 189; |  | ||||||
| pub const SYS_FSETXATTR: u32 = 190; |  | ||||||
| pub const SYS_GETXATTR: u32 = 191; |  | ||||||
| pub const SYS_LGETXATTR: u32 = 192; |  | ||||||
| pub const SYS_FGETXATTR: u32 = 193; |  | ||||||
| pub const SYS_LISTXATTR: u32 = 194; |  | ||||||
| pub const SYS_LLISTXATTR: u32 = 195; |  | ||||||
| pub const SYS_FLISTXATTR: u32 = 196; |  | ||||||
| pub const SYS_REMOVEXATTR: u32 = 197; |  | ||||||
| pub const SYS_LREMOVEXATTR: u32 = 198; |  | ||||||
| pub const SYS_FREMOVEXATTR: u32 = 199; |  | ||||||
| pub const SYS_TKILL: u32 = 200; |  | ||||||
| pub const SYS_TIME: u32 = 201; |  | ||||||
| pub const SYS_FUTEX: u32 = 202; |  | ||||||
| pub const SYS_SCHED_SETAFFINITY: u32 = 203; |  | ||||||
| pub const SYS_SCHED_GETAFFINITY: u32 = 204; |  | ||||||
| pub const SYS_SET_THREAD_AREA: u32 = 205; |  | ||||||
| pub const SYS_IO_SETUP: u32 = 206; |  | ||||||
| pub const SYS_IO_DESTROY: u32 = 207; |  | ||||||
| pub const SYS_IO_GETEVENTS: u32 = 208; |  | ||||||
| pub const SYS_IO_SUBMIT: u32 = 209; |  | ||||||
| pub const SYS_IO_CANCEL: u32 = 210; |  | ||||||
| pub const SYS_GET_THREAD_AREA: u32 = 211; |  | ||||||
| pub const SYS_LOOKUP_DCOOKIE: u32 = 212; |  | ||||||
| pub const SYS_EPOLL_CREATE: u32 = 213; |  | ||||||
| pub const SYS_EPOLL_CTL_OLD: u32 = 214; |  | ||||||
| pub const SYS_EPOLL_WAIT_OLD: u32 = 215; |  | ||||||
| pub const SYS_REMAP_FILE_PAGES: u32 = 216; |  | ||||||
| pub const SYS_GETDENTS64: u32 = 217; |  | ||||||
| pub const SYS_SET_TID_ADDRESS: u32 = 218; |  | ||||||
| pub const SYS_RESTART_SYSCALL: u32 = 219; |  | ||||||
| pub const SYS_SEMTIMEDOP: u32 = 220; |  | ||||||
| pub const SYS_FADVISE64: u32 = 221; |  | ||||||
| pub const SYS_TIMER_CREATE: u32 = 222; |  | ||||||
| pub const SYS_TIMER_SETTIME: u32 = 223; |  | ||||||
| pub const SYS_TIMER_GETTIME: u32 = 224; |  | ||||||
| pub const SYS_TIMER_GETOVERRUN: u32 = 225; |  | ||||||
| pub const SYS_TIMER_DELETE: u32 = 226; |  | ||||||
| pub const SYS_CLOCK_SETTIME: u32 = 227; |  | ||||||
| pub const SYS_CLOCK_GETTIME: u32 = 228; |  | ||||||
| pub const SYS_CLOCK_GETRES: u32 = 229; |  | ||||||
| pub const SYS_CLOCK_NANOSLEEP: u32 = 230; |  | ||||||
| pub const SYS_EXIT_GROUP: u32 = 231; |  | ||||||
| pub const SYS_EPOLL_WAIT: u32 = 232; |  | ||||||
| pub const SYS_EPOLL_CTL: u32 = 233; |  | ||||||
| pub const SYS_TGKILL: u32 = 234; |  | ||||||
| pub const SYS_UTIMES: u32 = 235; |  | ||||||
| pub const SYS_VSERVER: u32 = 236; |  | ||||||
| pub const SYS_MBIND: u32 = 237; |  | ||||||
| pub const SYS_SET_MEMPOLICY: u32 = 238; |  | ||||||
| pub const SYS_GET_MEMPOLICY: u32 = 239; |  | ||||||
| pub const SYS_MQ_OPEN: u32 = 240; |  | ||||||
| pub const SYS_MQ_UNLINK: u32 = 241; |  | ||||||
| pub const SYS_MQ_TIMEDSEND: u32 = 242; |  | ||||||
| pub const SYS_MQ_TIMEDRECEIVE: u32 = 243; |  | ||||||
| pub const SYS_MQ_NOTIFY: u32 = 244; |  | ||||||
| pub const SYS_MQ_GETSETATTR: u32 = 245; |  | ||||||
| pub const SYS_KEXEC_LOAD: u32 = 246; |  | ||||||
| pub const SYS_WAITID: u32 = 247; |  | ||||||
| pub const SYS_ADD_KEY: u32 = 248; |  | ||||||
| pub const SYS_REQUEST_KEY: u32 = 249; |  | ||||||
| pub const SYS_KEYCTL: u32 = 250; |  | ||||||
| pub const SYS_IOPRIO_SET: u32 = 251; |  | ||||||
| pub const SYS_IOPRIO_GET: u32 = 252; |  | ||||||
| pub const SYS_INOTIFY_INIT: u32 = 253; |  | ||||||
| pub const SYS_INOTIFY_ADD_WATCH: u32 = 254; |  | ||||||
| pub const SYS_INOTIFY_RM_WATCH: u32 = 255; |  | ||||||
| pub const SYS_MIGRATE_PAGES: u32 = 256; |  | ||||||
| pub const SYS_OPENAT: u32 = 257; |  | ||||||
| pub const SYS_MKDIRAT: u32 = 258; |  | ||||||
| pub const SYS_MKNODAT: u32 = 259; |  | ||||||
| pub const SYS_FCHOWNAT: u32 = 260; |  | ||||||
| pub const SYS_FUTIMESAT: u32 = 261; |  | ||||||
| pub const SYS_NEWFSTATAT: u32 = 262; |  | ||||||
| pub const SYS_UNLINKAT: u32 = 263; |  | ||||||
| pub const SYS_RENAMEAT: u32 = 264; |  | ||||||
| pub const SYS_LINKAT: u32 = 265; |  | ||||||
| pub const SYS_SYMLINKAT: u32 = 266; |  | ||||||
| pub const SYS_READLINKAT: u32 = 267; |  | ||||||
| pub const SYS_FCHMODAT: u32 = 268; |  | ||||||
| pub const SYS_FACCESSAT: u32 = 269; |  | ||||||
| pub const SYS_PSELECT6: u32 = 270; |  | ||||||
| pub const SYS_PPOLL: u32 = 271; |  | ||||||
| pub const SYS_UNSHARE: u32 = 272; |  | ||||||
| pub const SYS_SET_ROBUST_LIST: u32 = 273; |  | ||||||
| pub const SYS_GET_ROBUST_LIST: u32 = 274; |  | ||||||
| pub const SYS_SPLICE: u32 = 275; |  | ||||||
| pub const SYS_TEE: u32 = 276; |  | ||||||
| pub const SYS_SYNC_FILE_RANGE: u32 = 277; |  | ||||||
| pub const SYS_VMSPLICE: u32 = 278; |  | ||||||
| pub const SYS_MOVE_PAGES: u32 = 279; |  | ||||||
| pub const SYS_UTIMENSAT: u32 = 280; |  | ||||||
| pub const SYS_EPOLL_PWAIT: u32 = 281; |  | ||||||
| pub const SYS_SIGNALFD: u32 = 282; |  | ||||||
| pub const SYS_TIMERFD_CREATE: u32 = 283; |  | ||||||
| pub const SYS_EVENTFD: u32 = 284; |  | ||||||
| pub const SYS_FALLOCATE: u32 = 285; |  | ||||||
| pub const SYS_TIMERFD_SETTIME: u32 = 286; |  | ||||||
| pub const SYS_TIMERFD_GETTIME: u32 = 287; |  | ||||||
| pub const SYS_ACCEPT4: u32 = 288; |  | ||||||
| pub const SYS_SIGNALFD4: u32 = 289; |  | ||||||
| pub const SYS_EVENTFD2: u32 = 290; |  | ||||||
| pub const SYS_EPOLL_CREATE1: u32 = 291; |  | ||||||
| pub const SYS_DUP3: u32 = 292; |  | ||||||
| pub const SYS_PIPE2: u32 = 293; |  | ||||||
| pub const SYS_INOTIFY_INIT1: u32 = 294; |  | ||||||
| pub const SYS_PREADV: u32 = 295; |  | ||||||
| pub const SYS_PWRITEV: u32 = 296; |  | ||||||
| pub const SYS_RT_TGSIGQUEUEINFO: u32 = 297; |  | ||||||
| pub const SYS_PERF_EVENT_OPEN: u32 = 298; |  | ||||||
| pub const SYS_RECVMMSG: u32 = 299; |  | ||||||
| pub const SYS_FANOTIFY_INIT: u32 = 300; |  | ||||||
| pub const SYS_FANOTIFY_MARK: u32 = 301; |  | ||||||
| pub const SYS_PRLIMIT64: u32 = 302; |  | ||||||
| pub const SYS_NAME_TO_HANDLE_AT: u32 = 303; |  | ||||||
| pub const SYS_OPEN_BY_HANDLE_AT: u32 = 304; |  | ||||||
| pub const SYS_CLOCK_ADJTIME: u32 = 305; |  | ||||||
| pub const SYS_SYNCFS: u32 = 306; |  | ||||||
| pub const SYS_SENDMMSG: u32 = 307; |  | ||||||
| pub const SYS_SETNS: u32 = 308; |  | ||||||
| pub const SYS_GETCPU: u32 = 309; |  | ||||||
| pub const SYS_PROCESS_VM_READV: u32 = 310; |  | ||||||
| pub const SYS_PROCESS_VM_WRITEV: u32 = 311; |  | ||||||
| pub const SYS_KCMP: u32 = 312; |  | ||||||
| pub const SYS_FINIT_MODULE: u32 = 313; |  | ||||||
| pub const SYS_SCHED_SETATTR: u32 = 314; |  | ||||||
| pub const SYS_SCHED_GETATTR: u32 = 315; |  | ||||||
| pub const SYS_RENAMEAT2: u32 = 316; |  | ||||||
| pub const SYS_SECCOMP: u32 = 317; |  | ||||||
| pub const SYS_GETRANDOM: u32 = 318; |  | ||||||
| pub const SYS_MEMFD_CREATE: u32 = 319; |  | ||||||
| pub const SYS_KEXEC_FILE_LOAD: u32 = 320; |  | ||||||
| pub const SYS_BPF: u32 = 321; |  | ||||||
| pub const SYS_EXECVEAT: u32 = 322; |  | ||||||
| pub const SYS_USERFAULTFD: u32 = 323; |  | ||||||
| pub const SYS_MEMBARRIER: u32 = 324; |  | ||||||
| pub const SYS_MLOCK2: u32 = 325; |  | ||||||
| 
 |  | ||||||
| pub const SYS_SPAWN: u32 = 360; |  | ||||||
| @ -6,32 +6,30 @@ | |||||||
| //! 2. Do some bound checks then call `dispatch_syscall` (at this file)
 | //! 2. Do some bound checks then call `dispatch_syscall` (at this file)
 | ||||||
| //! 3. Dispatch the syscall to `do_*` (at this file)
 | //! 3. Dispatch the syscall to `do_*` (at this file)
 | ||||||
| //! 4. Do some memory checks then call `mod::do_*` (at each module)
 | //! 4. Do some memory checks then call `mod::do_*` (at each module)
 | ||||||
|  | pub use self::syscall_num::SyscallNum; | ||||||
| 
 | 
 | ||||||
| use fs::{File, FileDesc, FileRef, Stat}; | use fs::{File, FileDesc, FileRef, Stat}; | ||||||
| use misc::{resource_t, rlimit_t, utsname_t}; | use misc::{resource_t, rlimit_t, utsname_t}; | ||||||
| use net::{msghdr, msghdr_mut, AsSocket, AsUnixSocket, SocketFile, UnixSocketFile}; | use net::{msghdr, msghdr_mut, AsSocket, AsUnixSocket, SocketFile, UnixSocketFile}; | ||||||
| use process::{pid_t, ChildProcessFilter, CloneFlags, CpuSet, FileAction, FutexFlags, FutexOp}; | use process::{pid_t, ChildProcessFilter, CloneFlags, CpuSet, FileAction, FutexFlags, FutexOp}; | ||||||
|  | use std::any::Any; | ||||||
|  | use std::convert::TryFrom; | ||||||
| use std::ffi::{CStr, CString}; | use std::ffi::{CStr, CString}; | ||||||
|  | use std::io::{Read, Seek, SeekFrom, Write}; | ||||||
| use std::ptr; | use std::ptr; | ||||||
| use time::{clockid_t, timespec_t, timeval_t}; | use time::{clockid_t, timespec_t, timeval_t, GLOBAL_PROFILER}; | ||||||
| use util::mem_util::from_user::*; | use util::mem_util::from_user::*; | ||||||
| use vm::{MMapFlags, VMPerms}; | use vm::{MMapFlags, VMPerms}; | ||||||
| use {fs, process, std, vm}; | use {fs, process, std, vm}; | ||||||
| 
 | 
 | ||||||
| use super::*; | use super::*; | ||||||
| 
 | 
 | ||||||
| use self::consts::*; | mod syscall_num; | ||||||
| use std::any::Any; |  | ||||||
| use std::io::{Read, Seek, SeekFrom, Write}; |  | ||||||
| 
 | 
 | ||||||
| // Use the internal syscall wrappers from sgx_tstd
 | // Use the internal syscall wrappers from sgx_tstd
 | ||||||
| //use std::libc_fs as fs;
 | //use std::libc_fs as fs;
 | ||||||
| //use std::libc_io as io;
 | //use std::libc_io as io;
 | ||||||
| 
 | 
 | ||||||
| mod consts; |  | ||||||
| 
 |  | ||||||
| static mut SYSCALL_TIMING: [usize; 361] = [0; 361]; |  | ||||||
| 
 |  | ||||||
| #[no_mangle] | #[no_mangle] | ||||||
| #[deny(unreachable_patterns)] | #[deny(unreachable_patterns)] | ||||||
| pub extern "C" fn dispatch_syscall( | pub extern "C" fn dispatch_syscall( | ||||||
| @ -43,167 +41,159 @@ pub extern "C" fn dispatch_syscall( | |||||||
|     arg4: isize, |     arg4: isize, | ||||||
|     arg5: isize, |     arg5: isize, | ||||||
| ) -> isize { | ) -> isize { | ||||||
|     debug!( |     let pid = process::do_gettid(); | ||||||
|         "syscall tid:{}, num:{}: {:#x}, {:#x}, {:#x}, {:#x}, {:#x}, {:#x}", |     let syscall_num = SyscallNum::try_from(num).unwrap(); | ||||||
|         process::do_gettid(), |  | ||||||
|         num, |  | ||||||
|         arg0, |  | ||||||
|         arg1, |  | ||||||
|         arg2, |  | ||||||
|         arg3, |  | ||||||
|         arg4, |  | ||||||
|         arg5 |  | ||||||
|     ); |  | ||||||
|     #[cfg(feature = "syscall_timing")] |  | ||||||
|     let time_start = { |  | ||||||
|         static mut LAST_PRINT: usize = 0; |  | ||||||
|         let time = crate::time::do_gettimeofday().as_usec(); |  | ||||||
|         unsafe { |  | ||||||
|             if time / 1000000 / 5 > LAST_PRINT { |  | ||||||
|                 LAST_PRINT = time / 1000000 / 5; |  | ||||||
|                 print_syscall_timing(); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         time |  | ||||||
|     }; |  | ||||||
| 
 | 
 | ||||||
|     let ret = match num { |     debug!( | ||||||
|  |         "syscall tid:{}, {:?}: {:#x}, {:#x}, {:#x}, {:#x}, {:#x}, {:#x}", | ||||||
|  |         pid, syscall_num, arg0, arg1, arg2, arg3, arg4, arg5 | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     #[cfg(feature = "syscall_timing")] | ||||||
|  |     GLOBAL_PROFILER | ||||||
|  |         .lock() | ||||||
|  |         .unwrap() | ||||||
|  |         .syscall_enter(syscall_num) | ||||||
|  |         .expect("unexpected error from profiler to enter syscall"); | ||||||
|  | 
 | ||||||
|  |     use self::syscall_num::SyscallNum::*; | ||||||
|  |     let ret = match syscall_num { | ||||||
|         // file
 |         // file
 | ||||||
|         SYS_OPEN => fs::do_open(arg0 as *const i8, arg1 as u32, arg2 as u32), |         SysOpen => fs::do_open(arg0 as *const i8, arg1 as u32, arg2 as u32), | ||||||
|         SYS_CLOSE => fs::do_close(arg0 as FileDesc), |         SysClose => fs::do_close(arg0 as FileDesc), | ||||||
|         SYS_READ => fs::do_read(arg0 as FileDesc, arg1 as *mut u8, arg2 as usize), |         SysRead => fs::do_read(arg0 as FileDesc, arg1 as *mut u8, arg2 as usize), | ||||||
|         SYS_WRITE => fs::do_write(arg0 as FileDesc, arg1 as *const u8, arg2 as usize), |         SysWrite => fs::do_write(arg0 as FileDesc, arg1 as *const u8, arg2 as usize), | ||||||
|         SYS_PREAD64 => fs::do_pread( |         SysPread64 => fs::do_pread( | ||||||
|             arg0 as FileDesc, |             arg0 as FileDesc, | ||||||
|             arg1 as *mut u8, |             arg1 as *mut u8, | ||||||
|             arg2 as usize, |             arg2 as usize, | ||||||
|             arg3 as usize, |             arg3 as usize, | ||||||
|         ), |         ), | ||||||
|         SYS_PWRITE64 => fs::do_pwrite( |         SysPwrite64 => fs::do_pwrite( | ||||||
|             arg0 as FileDesc, |             arg0 as FileDesc, | ||||||
|             arg1 as *const u8, |             arg1 as *const u8, | ||||||
|             arg2 as usize, |             arg2 as usize, | ||||||
|             arg3 as usize, |             arg3 as usize, | ||||||
|         ), |         ), | ||||||
|         SYS_READV => fs::do_readv(arg0 as FileDesc, arg1 as *mut fs::iovec_t, arg2 as i32), |         SysReadv => fs::do_readv(arg0 as FileDesc, arg1 as *mut fs::iovec_t, arg2 as i32), | ||||||
|         SYS_WRITEV => fs::do_writev(arg0 as FileDesc, arg1 as *mut fs::iovec_t, arg2 as i32), |         SysWritev => fs::do_writev(arg0 as FileDesc, arg1 as *mut fs::iovec_t, arg2 as i32), | ||||||
|         SYS_STAT => fs::do_stat(arg0 as *const i8, arg1 as *mut Stat), |         SysStat => fs::do_stat(arg0 as *const i8, arg1 as *mut Stat), | ||||||
|         SYS_FSTAT => fs::do_fstat(arg0 as FileDesc, arg1 as *mut Stat), |         SysFstat => fs::do_fstat(arg0 as FileDesc, arg1 as *mut Stat), | ||||||
|         SYS_LSTAT => fs::do_lstat(arg0 as *const i8, arg1 as *mut Stat), |         SysLstat => fs::do_lstat(arg0 as *const i8, arg1 as *mut Stat), | ||||||
|         SYS_ACCESS => fs::do_access(arg0 as *const i8, arg1 as u32), |         SysAccess => fs::do_access(arg0 as *const i8, arg1 as u32), | ||||||
|         SYS_FACCESSAT => fs::do_faccessat(arg0 as i32, arg1 as *const i8, arg2 as u32, arg3 as u32), |         SysFaccessat => fs::do_faccessat(arg0 as i32, arg1 as *const i8, arg2 as u32, arg3 as u32), | ||||||
|         SYS_LSEEK => fs::do_lseek(arg0 as FileDesc, arg1 as off_t, arg2 as i32), |         SysLseek => fs::do_lseek(arg0 as FileDesc, arg1 as off_t, arg2 as i32), | ||||||
|         SYS_FSYNC => fs::do_fsync(arg0 as FileDesc), |         SysFsync => fs::do_fsync(arg0 as FileDesc), | ||||||
|         SYS_FDATASYNC => fs::do_fdatasync(arg0 as FileDesc), |         SysFdatasync => fs::do_fdatasync(arg0 as FileDesc), | ||||||
|         SYS_TRUNCATE => fs::do_truncate(arg0 as *const i8, arg1 as usize), |         SysTruncate => fs::do_truncate(arg0 as *const i8, arg1 as usize), | ||||||
|         SYS_FTRUNCATE => fs::do_ftruncate(arg0 as FileDesc, arg1 as usize), |         SysFtruncate => fs::do_ftruncate(arg0 as FileDesc, arg1 as usize), | ||||||
|         SYS_GETDENTS64 => fs::do_getdents64(arg0 as FileDesc, arg1 as *mut u8, arg2 as usize), |         SysGetdents64 => fs::do_getdents64(arg0 as FileDesc, arg1 as *mut u8, arg2 as usize), | ||||||
|         SYS_SYNC => fs::do_sync(), |         SysSync => fs::do_sync(), | ||||||
|         SYS_GETCWD => do_getcwd(arg0 as *mut u8, arg1 as usize), |         SysGetcwd => do_getcwd(arg0 as *mut u8, arg1 as usize), | ||||||
|         SYS_CHDIR => fs::do_chdir(arg0 as *mut i8), |         SysChdir => fs::do_chdir(arg0 as *mut i8), | ||||||
|         SYS_RENAME => fs::do_rename(arg0 as *const i8, arg1 as *const i8), |         SysRename => fs::do_rename(arg0 as *const i8, arg1 as *const i8), | ||||||
|         SYS_MKDIR => fs::do_mkdir(arg0 as *const i8, arg1 as usize), |         SysMkdir => fs::do_mkdir(arg0 as *const i8, arg1 as usize), | ||||||
|         SYS_RMDIR => fs::do_rmdir(arg0 as *const i8), |         SysRmdir => fs::do_rmdir(arg0 as *const i8), | ||||||
|         SYS_LINK => fs::do_link(arg0 as *const i8, arg1 as *const i8), |         SysLink => fs::do_link(arg0 as *const i8, arg1 as *const i8), | ||||||
|         SYS_UNLINK => fs::do_unlink(arg0 as *const i8), |         SysUnlink => fs::do_unlink(arg0 as *const i8), | ||||||
|         SYS_READLINK => fs::do_readlink(arg0 as *const i8, arg1 as *mut u8, arg2 as usize), |         SysReadlink => fs::do_readlink(arg0 as *const i8, arg1 as *mut u8, arg2 as usize), | ||||||
|         SYS_SENDFILE => fs::do_sendfile( |         SysSendfile => fs::do_sendfile( | ||||||
|             arg0 as FileDesc, |             arg0 as FileDesc, | ||||||
|             arg1 as FileDesc, |             arg1 as FileDesc, | ||||||
|             arg2 as *mut off_t, |             arg2 as *mut off_t, | ||||||
|             arg3 as usize, |             arg3 as usize, | ||||||
|         ), |         ), | ||||||
|         SYS_FCNTL => fs::do_fcntl(arg0 as FileDesc, arg1 as u32, arg2 as u64), |         SysFcntl => fs::do_fcntl(arg0 as FileDesc, arg1 as u32, arg2 as u64), | ||||||
|         SYS_IOCTL => fs::do_ioctl(arg0 as FileDesc, arg1 as u32, arg2 as *mut u8), |         SysIoctl => fs::do_ioctl(arg0 as FileDesc, arg1 as u32, arg2 as *mut u8), | ||||||
| 
 | 
 | ||||||
|         // IO multiplexing
 |         // Io multiplexing
 | ||||||
|         SYS_SELECT => net::do_select( |         SysSelect => net::do_select( | ||||||
|             arg0 as c_int, |             arg0 as c_int, | ||||||
|             arg1 as *mut libc::fd_set, |             arg1 as *mut libc::fd_set, | ||||||
|             arg2 as *mut libc::fd_set, |             arg2 as *mut libc::fd_set, | ||||||
|             arg3 as *mut libc::fd_set, |             arg3 as *mut libc::fd_set, | ||||||
|             arg4 as *const libc::timeval, |             arg4 as *const libc::timeval, | ||||||
|         ), |         ), | ||||||
|         SYS_POLL => net::do_poll( |         SysPoll => net::do_poll( | ||||||
|             arg0 as *mut libc::pollfd, |             arg0 as *mut libc::pollfd, | ||||||
|             arg1 as libc::nfds_t, |             arg1 as libc::nfds_t, | ||||||
|             arg2 as c_int, |             arg2 as c_int, | ||||||
|         ), |         ), | ||||||
|         SYS_EPOLL_CREATE => net::do_epoll_create(arg0 as c_int), |         SysEpollCreate => net::do_epoll_create(arg0 as c_int), | ||||||
|         SYS_EPOLL_CREATE1 => net::do_epoll_create1(arg0 as c_int), |         SysEpollCreate1 => net::do_epoll_create1(arg0 as c_int), | ||||||
|         SYS_EPOLL_CTL => net::do_epoll_ctl( |         SysEpollCtl => net::do_epoll_ctl( | ||||||
|             arg0 as c_int, |             arg0 as c_int, | ||||||
|             arg1 as c_int, |             arg1 as c_int, | ||||||
|             arg2 as c_int, |             arg2 as c_int, | ||||||
|             arg3 as *const libc::epoll_event, |             arg3 as *const libc::epoll_event, | ||||||
|         ), |         ), | ||||||
|         SYS_EPOLL_WAIT => net::do_epoll_wait( |         SysEpollWait => net::do_epoll_wait( | ||||||
|             arg0 as c_int, |             arg0 as c_int, | ||||||
|             arg1 as *mut libc::epoll_event, |             arg1 as *mut libc::epoll_event, | ||||||
|             arg2 as c_int, |             arg2 as c_int, | ||||||
|             arg3 as c_int, |             arg3 as c_int, | ||||||
|         ), |         ), | ||||||
|         SYS_EPOLL_PWAIT => net::do_epoll_pwait( |         SysEpollPwait => net::do_epoll_pwait( | ||||||
|             arg0 as c_int, |             arg0 as c_int, | ||||||
|             arg1 as *mut libc::epoll_event, |             arg1 as *mut libc::epoll_event, | ||||||
|             arg2 as c_int, |             arg2 as c_int, | ||||||
|             arg3 as c_int, |             arg3 as c_int, | ||||||
|             arg4 as *const usize, //TODO:add sigset_t
 |             arg4 as *const usize, //Todo:add sigset_t
 | ||||||
|         ), |         ), | ||||||
| 
 | 
 | ||||||
|         // process
 |         // process
 | ||||||
|         SYS_EXIT => do_exit(arg0 as i32), |         SysExit => do_exit(arg0 as i32), | ||||||
|         SYS_SPAWN => do_spawn( |         SysSpawn => do_spawn( | ||||||
|             arg0 as *mut u32, |             arg0 as *mut u32, | ||||||
|             arg1 as *mut i8, |             arg1 as *mut i8, | ||||||
|             arg2 as *const *const i8, |             arg2 as *const *const i8, | ||||||
|             arg3 as *const *const i8, |             arg3 as *const *const i8, | ||||||
|             arg4 as *const FdOp, |             arg4 as *const FdOp, | ||||||
|         ), |         ), | ||||||
|         SYS_WAIT4 => do_wait4(arg0 as i32, arg1 as *mut i32), |         SysWait4 => do_wait4(arg0 as i32, arg1 as *mut i32), | ||||||
| 
 | 
 | ||||||
|         SYS_GETPID => do_getpid(), |         SysGetpid => do_getpid(), | ||||||
|         SYS_GETTID => do_gettid(), |         SysGettid => do_gettid(), | ||||||
|         SYS_GETPPID => do_getppid(), |         SysGetppid => do_getppid(), | ||||||
|         SYS_GETPGID => do_getpgid(), |         SysGetpgid => do_getpgid(), | ||||||
| 
 | 
 | ||||||
|         SYS_GETUID => do_getuid(), |         SysGetuid => do_getuid(), | ||||||
|         SYS_GETGID => do_getgid(), |         SysGetgid => do_getgid(), | ||||||
|         SYS_GETEUID => do_geteuid(), |         SysGeteuid => do_geteuid(), | ||||||
|         SYS_GETEGID => do_getegid(), |         SysGetegid => do_getegid(), | ||||||
| 
 | 
 | ||||||
|         SYS_RT_SIGACTION => do_rt_sigaction(), |         SysRtSigaction => do_rt_sigaction(), | ||||||
|         SYS_RT_SIGPROCMASK => do_rt_sigprocmask(), |         SysRtSigprocmask => do_rt_sigprocmask(), | ||||||
| 
 | 
 | ||||||
|         SYS_CLONE => do_clone( |         SysClone => do_clone( | ||||||
|             arg0 as u32, |             arg0 as u32, | ||||||
|             arg1 as usize, |             arg1 as usize, | ||||||
|             arg2 as *mut pid_t, |             arg2 as *mut pid_t, | ||||||
|             arg3 as *mut pid_t, |             arg3 as *mut pid_t, | ||||||
|             arg4 as usize, |             arg4 as usize, | ||||||
|         ), |         ), | ||||||
|         SYS_FUTEX => do_futex( |         SysFutex => do_futex( | ||||||
|             arg0 as *const i32, |             arg0 as *const i32, | ||||||
|             arg1 as u32, |             arg1 as u32, | ||||||
|             arg2 as i32, |             arg2 as i32, | ||||||
|             arg3 as i32, |             arg3 as i32, | ||||||
|             arg4 as *const i32, |             arg4 as *const i32, | ||||||
|             // TODO: accept other optional arguments
 |             // Todo: accept other optional arguments
 | ||||||
|         ), |         ), | ||||||
|         SYS_ARCH_PRCTL => do_arch_prctl(arg0 as u32, arg1 as *mut usize), |         SysArchPrctl => do_arch_prctl(arg0 as u32, arg1 as *mut usize), | ||||||
|         SYS_SET_TID_ADDRESS => do_set_tid_address(arg0 as *mut pid_t), |         SysSetTidAddress => do_set_tid_address(arg0 as *mut pid_t), | ||||||
| 
 | 
 | ||||||
|         // sched
 |         // sched
 | ||||||
|         SYS_SCHED_YIELD => do_sched_yield(), |         SysSchedYield => do_sched_yield(), | ||||||
|         SYS_SCHED_GETAFFINITY => { |         SysSchedGetaffinity => { | ||||||
|             do_sched_getaffinity(arg0 as pid_t, arg1 as size_t, arg2 as *mut c_uchar) |             do_sched_getaffinity(arg0 as pid_t, arg1 as size_t, arg2 as *mut c_uchar) | ||||||
|         } |         } | ||||||
|         SYS_SCHED_SETAFFINITY => { |         SysSchedSetaffinity => { | ||||||
|             do_sched_setaffinity(arg0 as pid_t, arg1 as size_t, arg2 as *const c_uchar) |             do_sched_setaffinity(arg0 as pid_t, arg1 as size_t, arg2 as *const c_uchar) | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // memory
 |         // memory
 | ||||||
|         SYS_MMAP => do_mmap( |         SysMmap => do_mmap( | ||||||
|             arg0 as usize, |             arg0 as usize, | ||||||
|             arg1 as usize, |             arg1 as usize, | ||||||
|             arg2 as i32, |             arg2 as i32, | ||||||
| @ -211,31 +201,31 @@ pub extern "C" fn dispatch_syscall( | |||||||
|             arg4 as FileDesc, |             arg4 as FileDesc, | ||||||
|             arg5 as off_t, |             arg5 as off_t, | ||||||
|         ), |         ), | ||||||
|         SYS_MUNMAP => do_munmap(arg0 as usize, arg1 as usize), |         SysMunmap => do_munmap(arg0 as usize, arg1 as usize), | ||||||
|         SYS_MREMAP => do_mremap( |         SysMremap => do_mremap( | ||||||
|             arg0 as usize, |             arg0 as usize, | ||||||
|             arg1 as usize, |             arg1 as usize, | ||||||
|             arg2 as usize, |             arg2 as usize, | ||||||
|             arg3 as i32, |             arg3 as i32, | ||||||
|             arg4 as usize, |             arg4 as usize, | ||||||
|         ), |         ), | ||||||
|         SYS_MPROTECT => do_mprotect(arg0 as usize, arg1 as usize, arg2 as u32), |         SysMprotect => do_mprotect(arg0 as usize, arg1 as usize, arg2 as u32), | ||||||
|         SYS_BRK => do_brk(arg0 as usize), |         SysBrk => do_brk(arg0 as usize), | ||||||
| 
 | 
 | ||||||
|         SYS_PIPE => fs::do_pipe2(arg0 as *mut i32, 0), |         SysPipe => fs::do_pipe2(arg0 as *mut i32, 0), | ||||||
|         SYS_PIPE2 => fs::do_pipe2(arg0 as *mut i32, arg1 as u32), |         SysPipe2 => fs::do_pipe2(arg0 as *mut i32, arg1 as u32), | ||||||
|         SYS_DUP => fs::do_dup(arg0 as FileDesc), |         SysDup => fs::do_dup(arg0 as FileDesc), | ||||||
|         SYS_DUP2 => fs::do_dup2(arg0 as FileDesc, arg1 as FileDesc), |         SysDup2 => fs::do_dup2(arg0 as FileDesc, arg1 as FileDesc), | ||||||
|         SYS_DUP3 => fs::do_dup3(arg0 as FileDesc, arg1 as FileDesc, arg2 as u32), |         SysDup3 => fs::do_dup3(arg0 as FileDesc, arg1 as FileDesc, arg2 as u32), | ||||||
| 
 | 
 | ||||||
|         SYS_GETTIMEOFDAY => do_gettimeofday(arg0 as *mut timeval_t), |         SysGettimeofday => do_gettimeofday(arg0 as *mut timeval_t), | ||||||
|         SYS_CLOCK_GETTIME => do_clock_gettime(arg0 as clockid_t, arg1 as *mut timespec_t), |         SysClockGettime => do_clock_gettime(arg0 as clockid_t, arg1 as *mut timespec_t), | ||||||
| 
 | 
 | ||||||
|         SYS_NANOSLEEP => do_nanosleep(arg0 as *const timespec_t, arg1 as *mut timespec_t), |         SysNanosleep => do_nanosleep(arg0 as *const timespec_t, arg1 as *mut timespec_t), | ||||||
| 
 | 
 | ||||||
|         SYS_UNAME => do_uname(arg0 as *mut utsname_t), |         SysUname => do_uname(arg0 as *mut utsname_t), | ||||||
| 
 | 
 | ||||||
|         SYS_PRLIMIT64 => do_prlimit( |         SysPrlimit64 => do_prlimit( | ||||||
|             arg0 as pid_t, |             arg0 as pid_t, | ||||||
|             arg1 as u32, |             arg1 as u32, | ||||||
|             arg2 as *const rlimit_t, |             arg2 as *const rlimit_t, | ||||||
| @ -243,56 +233,56 @@ pub extern "C" fn dispatch_syscall( | |||||||
|         ), |         ), | ||||||
| 
 | 
 | ||||||
|         // socket
 |         // socket
 | ||||||
|         SYS_SOCKET => do_socket(arg0 as c_int, arg1 as c_int, arg2 as c_int), |         SysSocket => do_socket(arg0 as c_int, arg1 as c_int, arg2 as c_int), | ||||||
|         SYS_CONNECT => do_connect( |         SysConnect => do_connect( | ||||||
|             arg0 as c_int, |             arg0 as c_int, | ||||||
|             arg1 as *const libc::sockaddr, |             arg1 as *const libc::sockaddr, | ||||||
|             arg2 as libc::socklen_t, |             arg2 as libc::socklen_t, | ||||||
|         ), |         ), | ||||||
|         SYS_ACCEPT => do_accept4( |         SysAccept => do_accept4( | ||||||
|             arg0 as c_int, |             arg0 as c_int, | ||||||
|             arg1 as *mut libc::sockaddr, |             arg1 as *mut libc::sockaddr, | ||||||
|             arg2 as *mut libc::socklen_t, |             arg2 as *mut libc::socklen_t, | ||||||
|             0, |             0, | ||||||
|         ), |         ), | ||||||
|         SYS_ACCEPT4 => do_accept4( |         SysAccept4 => do_accept4( | ||||||
|             arg0 as c_int, |             arg0 as c_int, | ||||||
|             arg1 as *mut libc::sockaddr, |             arg1 as *mut libc::sockaddr, | ||||||
|             arg2 as *mut libc::socklen_t, |             arg2 as *mut libc::socklen_t, | ||||||
|             arg3 as c_int, |             arg3 as c_int, | ||||||
|         ), |         ), | ||||||
|         SYS_SHUTDOWN => do_shutdown(arg0 as c_int, arg1 as c_int), |         SysShutdown => do_shutdown(arg0 as c_int, arg1 as c_int), | ||||||
|         SYS_BIND => do_bind( |         SysBind => do_bind( | ||||||
|             arg0 as c_int, |             arg0 as c_int, | ||||||
|             arg1 as *const libc::sockaddr, |             arg1 as *const libc::sockaddr, | ||||||
|             arg2 as libc::socklen_t, |             arg2 as libc::socklen_t, | ||||||
|         ), |         ), | ||||||
|         SYS_LISTEN => do_listen(arg0 as c_int, arg1 as c_int), |         SysListen => do_listen(arg0 as c_int, arg1 as c_int), | ||||||
|         SYS_SETSOCKOPT => do_setsockopt( |         SysSetsockopt => do_setsockopt( | ||||||
|             arg0 as c_int, |             arg0 as c_int, | ||||||
|             arg1 as c_int, |             arg1 as c_int, | ||||||
|             arg2 as c_int, |             arg2 as c_int, | ||||||
|             arg3 as *const c_void, |             arg3 as *const c_void, | ||||||
|             arg4 as libc::socklen_t, |             arg4 as libc::socklen_t, | ||||||
|         ), |         ), | ||||||
|         SYS_GETSOCKOPT => do_getsockopt( |         SysGetsockopt => do_getsockopt( | ||||||
|             arg0 as c_int, |             arg0 as c_int, | ||||||
|             arg1 as c_int, |             arg1 as c_int, | ||||||
|             arg2 as c_int, |             arg2 as c_int, | ||||||
|             arg3 as *mut c_void, |             arg3 as *mut c_void, | ||||||
|             arg4 as *mut libc::socklen_t, |             arg4 as *mut libc::socklen_t, | ||||||
|         ), |         ), | ||||||
|         SYS_GETPEERNAME => do_getpeername( |         SysGetpeername => do_getpeername( | ||||||
|             arg0 as c_int, |             arg0 as c_int, | ||||||
|             arg1 as *mut libc::sockaddr, |             arg1 as *mut libc::sockaddr, | ||||||
|             arg2 as *mut libc::socklen_t, |             arg2 as *mut libc::socklen_t, | ||||||
|         ), |         ), | ||||||
|         SYS_GETSOCKNAME => do_getsockname( |         SysGetsockname => do_getsockname( | ||||||
|             arg0 as c_int, |             arg0 as c_int, | ||||||
|             arg1 as *mut libc::sockaddr, |             arg1 as *mut libc::sockaddr, | ||||||
|             arg2 as *mut libc::socklen_t, |             arg2 as *mut libc::socklen_t, | ||||||
|         ), |         ), | ||||||
|         SYS_SENDTO => do_sendto( |         SysSendto => do_sendto( | ||||||
|             arg0 as c_int, |             arg0 as c_int, | ||||||
|             arg1 as *const c_void, |             arg1 as *const c_void, | ||||||
|             arg2 as size_t, |             arg2 as size_t, | ||||||
| @ -300,7 +290,7 @@ pub extern "C" fn dispatch_syscall( | |||||||
|             arg4 as *const libc::sockaddr, |             arg4 as *const libc::sockaddr, | ||||||
|             arg5 as libc::socklen_t, |             arg5 as libc::socklen_t, | ||||||
|         ), |         ), | ||||||
|         SYS_RECVFROM => do_recvfrom( |         SysRecvfrom => do_recvfrom( | ||||||
|             arg0 as c_int, |             arg0 as c_int, | ||||||
|             arg1 as *mut c_void, |             arg1 as *mut c_void, | ||||||
|             arg2 as size_t, |             arg2 as size_t, | ||||||
| @ -309,29 +299,27 @@ pub extern "C" fn dispatch_syscall( | |||||||
|             arg5 as *mut libc::socklen_t, |             arg5 as *mut libc::socklen_t, | ||||||
|         ), |         ), | ||||||
| 
 | 
 | ||||||
|         SYS_SOCKETPAIR => do_socketpair( |         SysSocketpair => do_socketpair( | ||||||
|             arg0 as c_int, |             arg0 as c_int, | ||||||
|             arg1 as c_int, |             arg1 as c_int, | ||||||
|             arg2 as c_int, |             arg2 as c_int, | ||||||
|             arg3 as *mut c_int, |             arg3 as *mut c_int, | ||||||
|         ), |         ), | ||||||
| 
 | 
 | ||||||
|         SYS_SENDMSG => net::do_sendmsg(arg0 as c_int, arg1 as *const msghdr, arg2 as c_int), |         SysSendmsg => net::do_sendmsg(arg0 as c_int, arg1 as *const msghdr, arg2 as c_int), | ||||||
|         SYS_RECVMSG => net::do_recvmsg(arg0 as c_int, arg1 as *mut msghdr_mut, arg2 as c_int), |         SysRecvmsg => net::do_recvmsg(arg0 as c_int, arg1 as *mut msghdr_mut, arg2 as c_int), | ||||||
| 
 | 
 | ||||||
|         _ => do_unknown(num, arg0, arg1, arg2, arg3, arg4, arg5), |         _ => do_unknown(num, arg0, arg1, arg2, arg3, arg4, arg5), | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     #[cfg(feature = "syscall_timing")] |     #[cfg(feature = "syscall_timing")] | ||||||
|     { |     GLOBAL_PROFILER | ||||||
|         let time_end = crate::time::do_gettimeofday().as_usec(); |         .lock() | ||||||
|         let time = time_end - time_start; |         .unwrap() | ||||||
|         unsafe { |         .syscall_exit(syscall_num, ret.is_err()) | ||||||
|             SYSCALL_TIMING[num as usize] += time as usize; |         .expect("unexpected error from profiler to exit syscall"); | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     info!("=> {:?}", ret); |     info!("tid: {} => {:?} ", process::do_gettid(), ret); | ||||||
| 
 | 
 | ||||||
|     match ret { |     match ret { | ||||||
|         Ok(retval) => retval as isize, |         Ok(retval) => retval as isize, | ||||||
| @ -345,20 +333,6 @@ pub extern "C" fn dispatch_syscall( | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[cfg(feature = "syscall_timing")] |  | ||||||
| fn print_syscall_timing() { |  | ||||||
|     println!("syscall timing:"); |  | ||||||
|     for (i, &time) in unsafe { SYSCALL_TIMING }.iter().enumerate() { |  | ||||||
|         if time == 0 { |  | ||||||
|             continue; |  | ||||||
|         } |  | ||||||
|         println!("{:>3}: {:>6} us", i, time); |  | ||||||
|     } |  | ||||||
|     for x in unsafe { SYSCALL_TIMING.iter_mut() } { |  | ||||||
|         *x = 0; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* | /* | ||||||
|  * This Rust-version of fdop correspond to the C-version one in Occlum. |  * This Rust-version of fdop correspond to the C-version one in Occlum. | ||||||
|  * See <path_to_musl_libc>/src/process/fdop.h. |  * See <path_to_musl_libc>/src/process/fdop.h. | ||||||
|  | |||||||
							
								
								
									
										345
									
								
								src/libos/src/syscall/syscall_num.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										345
									
								
								src/libos/src/syscall/syscall_num.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,345 @@ | |||||||
|  | use super::*; | ||||||
|  | 
 | ||||||
|  | #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)] | ||||||
|  | pub enum SyscallNum { | ||||||
|  |     SysRead = 0, | ||||||
|  |     SysWrite = 1, | ||||||
|  |     SysOpen = 2, | ||||||
|  |     SysClose = 3, | ||||||
|  |     SysStat = 4, | ||||||
|  |     SysFstat = 5, | ||||||
|  |     SysLstat = 6, | ||||||
|  |     SysPoll = 7, | ||||||
|  |     SysLseek = 8, | ||||||
|  |     SysMmap = 9, | ||||||
|  |     SysMprotect = 10, | ||||||
|  |     SysMunmap = 11, | ||||||
|  |     SysBrk = 12, | ||||||
|  |     SysRtSigaction = 13, | ||||||
|  |     SysRtSigprocmask = 14, | ||||||
|  |     SysRtSigreturn = 15, | ||||||
|  |     SysIoctl = 16, | ||||||
|  |     SysPread64 = 17, | ||||||
|  |     SysPwrite64 = 18, | ||||||
|  |     SysReadv = 19, | ||||||
|  |     SysWritev = 20, | ||||||
|  |     SysAccess = 21, | ||||||
|  |     SysPipe = 22, | ||||||
|  |     SysSelect = 23, | ||||||
|  |     SysSchedYield = 24, | ||||||
|  |     SysMremap = 25, | ||||||
|  |     SysMsync = 26, | ||||||
|  |     SysMincore = 27, | ||||||
|  |     SysMadvise = 28, | ||||||
|  |     SysShmget = 29, | ||||||
|  |     SysShmat = 30, | ||||||
|  |     SysShmctl = 31, | ||||||
|  |     SysDup = 32, | ||||||
|  |     SysDup2 = 33, | ||||||
|  |     SysPause = 34, | ||||||
|  |     SysNanosleep = 35, | ||||||
|  |     SysGetitimer = 36, | ||||||
|  |     SysAlarm = 37, | ||||||
|  |     SysSetitimer = 38, | ||||||
|  |     SysGetpid = 39, | ||||||
|  |     SysSendfile = 40, | ||||||
|  |     SysSocket = 41, | ||||||
|  |     SysConnect = 42, | ||||||
|  |     SysAccept = 43, | ||||||
|  |     SysSendto = 44, | ||||||
|  |     SysRecvfrom = 45, | ||||||
|  |     SysSendmsg = 46, | ||||||
|  |     SysRecvmsg = 47, | ||||||
|  |     SysShutdown = 48, | ||||||
|  |     SysBind = 49, | ||||||
|  |     SysListen = 50, | ||||||
|  |     SysGetsockname = 51, | ||||||
|  |     SysGetpeername = 52, | ||||||
|  |     SysSocketpair = 53, | ||||||
|  |     SysSetsockopt = 54, | ||||||
|  |     SysGetsockopt = 55, | ||||||
|  |     SysClone = 56, | ||||||
|  |     SysFork = 57, | ||||||
|  |     SysVfork = 58, | ||||||
|  |     SysExecve = 59, | ||||||
|  |     SysExit = 60, | ||||||
|  |     SysWait4 = 61, | ||||||
|  |     SysKill = 62, | ||||||
|  |     SysUname = 63, | ||||||
|  |     SysSemget = 64, | ||||||
|  |     SysSemop = 65, | ||||||
|  |     SysSemctl = 66, | ||||||
|  |     SysShmdt = 67, | ||||||
|  |     SysMsgget = 68, | ||||||
|  |     SysMsgsnd = 69, | ||||||
|  |     SysMsgrcv = 70, | ||||||
|  |     SysMsgctl = 71, | ||||||
|  |     SysFcntl = 72, | ||||||
|  |     SysFlock = 73, | ||||||
|  |     SysFsync = 74, | ||||||
|  |     SysFdatasync = 75, | ||||||
|  |     SysTruncate = 76, | ||||||
|  |     SysFtruncate = 77, | ||||||
|  |     SysGetdents = 78, | ||||||
|  |     SysGetcwd = 79, | ||||||
|  |     SysChdir = 80, | ||||||
|  |     SysFchdir = 81, | ||||||
|  |     SysRename = 82, | ||||||
|  |     SysMkdir = 83, | ||||||
|  |     SysRmdir = 84, | ||||||
|  |     SysCreat = 85, | ||||||
|  |     SysLink = 86, | ||||||
|  |     SysUnlink = 87, | ||||||
|  |     SysSymlink = 88, | ||||||
|  |     SysReadlink = 89, | ||||||
|  |     SysChmod = 90, | ||||||
|  |     SysFchmod = 91, | ||||||
|  |     SysChown = 92, | ||||||
|  |     SysFchown = 93, | ||||||
|  |     SysLchown = 94, | ||||||
|  |     SysUmask = 95, | ||||||
|  |     SysGettimeofday = 96, | ||||||
|  |     SysGetrlimit = 97, | ||||||
|  |     SysGetrusage = 98, | ||||||
|  |     SysSysInfo = 99, | ||||||
|  |     SysTimes = 100, | ||||||
|  |     SysPtrace = 101, | ||||||
|  |     SysGetuid = 102, | ||||||
|  |     SysSysLog = 103, | ||||||
|  |     SysGetgid = 104, | ||||||
|  |     SysSetuid = 105, | ||||||
|  |     SysSetgid = 106, | ||||||
|  |     SysGeteuid = 107, | ||||||
|  |     SysGetegid = 108, | ||||||
|  |     SysSetpgid = 109, | ||||||
|  |     SysGetppid = 110, | ||||||
|  |     SysGetpgrp = 111, | ||||||
|  |     SysSetsid = 112, | ||||||
|  |     SysSetreuid = 113, | ||||||
|  |     SysSetregid = 114, | ||||||
|  |     SysGetgroups = 115, | ||||||
|  |     SysSetgroups = 116, | ||||||
|  |     SysSetresuid = 117, | ||||||
|  |     SysGetresuid = 118, | ||||||
|  |     SysSetresgid = 119, | ||||||
|  |     SysGetresgid = 120, | ||||||
|  |     SysGetpgid = 121, | ||||||
|  |     SysSetfsuid = 122, | ||||||
|  |     SysSetfsgid = 123, | ||||||
|  |     SysGetsid = 124, | ||||||
|  |     SysCapget = 125, | ||||||
|  |     SysCapset = 126, | ||||||
|  |     SysRtSigpending = 127, | ||||||
|  |     SysRtSigtimedwait = 128, | ||||||
|  |     SysRtSigqueueinfo = 129, | ||||||
|  |     SysRtSigsuspend = 130, | ||||||
|  |     SysSigaltstack = 131, | ||||||
|  |     SysUtime = 132, | ||||||
|  |     SysMknod = 133, | ||||||
|  |     SysUselib = 134, | ||||||
|  |     SysPersonality = 135, | ||||||
|  |     SysUstat = 136, | ||||||
|  |     SysStatfs = 137, | ||||||
|  |     SysFstatfs = 138, | ||||||
|  |     SysSysFs = 139, | ||||||
|  |     SysGetpriority = 140, | ||||||
|  |     SysSetpriority = 141, | ||||||
|  |     SysSchedSetparam = 142, | ||||||
|  |     SysSchedGetparam = 143, | ||||||
|  |     SysSchedSetscheduler = 144, | ||||||
|  |     SysSchedGetscheduler = 145, | ||||||
|  |     SysSchedGetPriorityMax = 146, | ||||||
|  |     SysSchedGetPriorityMin = 147, | ||||||
|  |     SysSchedRrGetInterval = 148, | ||||||
|  |     SysMlock = 149, | ||||||
|  |     SysMunlock = 150, | ||||||
|  |     SysMlockall = 151, | ||||||
|  |     SysMunlockall = 152, | ||||||
|  |     SysVhangup = 153, | ||||||
|  |     SysModifyLdt = 154, | ||||||
|  |     SysPivotRoot = 155, | ||||||
|  |     SysSysCtl = 156, | ||||||
|  |     SysPrctl = 157, | ||||||
|  |     SysArchPrctl = 158, | ||||||
|  |     SysAdjtimex = 159, | ||||||
|  |     SysSetrlimit = 160, | ||||||
|  |     SysChroot = 161, | ||||||
|  |     SysSync = 162, | ||||||
|  |     SysAcct = 163, | ||||||
|  |     SysSettimeofday = 164, | ||||||
|  |     SysMount = 165, | ||||||
|  |     SysUmount2 = 166, | ||||||
|  |     SysSwapon = 167, | ||||||
|  |     SysSwapoff = 168, | ||||||
|  |     SysReboot = 169, | ||||||
|  |     SysSethostname = 170, | ||||||
|  |     SysSetdomainname = 171, | ||||||
|  |     SysIopl = 172, | ||||||
|  |     SysIoperm = 173, | ||||||
|  |     SysCreateModule = 174, | ||||||
|  |     SysInitModule = 175, | ||||||
|  |     SysDeleteModule = 176, | ||||||
|  |     SysGetKernelSyms = 177, | ||||||
|  |     SysQueryModule = 178, | ||||||
|  |     SysQuotactl = 179, | ||||||
|  |     SysNfsservctl = 180, | ||||||
|  |     SysGetpmsg = 181, | ||||||
|  |     SysPutpmsg = 182, | ||||||
|  |     SysAfsSysCall = 183, | ||||||
|  |     SysTuxcall = 184, | ||||||
|  |     SysSecurity = 185, | ||||||
|  |     SysGettid = 186, | ||||||
|  |     SysReadahead = 187, | ||||||
|  |     SysSetxattr = 188, | ||||||
|  |     SysLsetxattr = 189, | ||||||
|  |     SysFsetxattr = 190, | ||||||
|  |     SysGetxattr = 191, | ||||||
|  |     SysLgetxattr = 192, | ||||||
|  |     SysFgetxattr = 193, | ||||||
|  |     SysListxattr = 194, | ||||||
|  |     SysLlistxattr = 195, | ||||||
|  |     SysFlistxattr = 196, | ||||||
|  |     SysRemovexattr = 197, | ||||||
|  |     SysLremovexattr = 198, | ||||||
|  |     SysFremovexattr = 199, | ||||||
|  |     SysTkill = 200, | ||||||
|  |     SysTime = 201, | ||||||
|  |     SysFutex = 202, | ||||||
|  |     SysSchedSetaffinity = 203, | ||||||
|  |     SysSchedGetaffinity = 204, | ||||||
|  |     SysSetThreadArea = 205, | ||||||
|  |     SysIoSetup = 206, | ||||||
|  |     SysIoDestroy = 207, | ||||||
|  |     SysIoGetevents = 208, | ||||||
|  |     SysIoSubmit = 209, | ||||||
|  |     SysIoCancel = 210, | ||||||
|  |     SysGetThreadArea = 211, | ||||||
|  |     SysLookupDcookie = 212, | ||||||
|  |     SysEpollCreate = 213, | ||||||
|  |     SysEpollCtlOld = 214, | ||||||
|  |     SysEpollWaitOld = 215, | ||||||
|  |     SysRemapFilePages = 216, | ||||||
|  |     SysGetdents64 = 217, | ||||||
|  |     SysSetTidAddress = 218, | ||||||
|  |     SysRestartSysCall = 219, | ||||||
|  |     SysSemtimedop = 220, | ||||||
|  |     SysFadvise64 = 221, | ||||||
|  |     SysTimerCreate = 222, | ||||||
|  |     SysTimerSettime = 223, | ||||||
|  |     SysTimerGettime = 224, | ||||||
|  |     SysTimerGetoverrun = 225, | ||||||
|  |     SysTimerDelete = 226, | ||||||
|  |     SysClockSettime = 227, | ||||||
|  |     SysClockGettime = 228, | ||||||
|  |     SysClockGetres = 229, | ||||||
|  |     SysClockNanosleep = 230, | ||||||
|  |     SysExitGroup = 231, | ||||||
|  |     SysEpollWait = 232, | ||||||
|  |     SysEpollCtl = 233, | ||||||
|  |     SysTgkill = 234, | ||||||
|  |     SysUtimes = 235, | ||||||
|  |     SysVserver = 236, | ||||||
|  |     SysMbind = 237, | ||||||
|  |     SysSetMempolicy = 238, | ||||||
|  |     SysGetMempolicy = 239, | ||||||
|  |     SysMqOpen = 240, | ||||||
|  |     SysMqUnlink = 241, | ||||||
|  |     SysMqTimedsend = 242, | ||||||
|  |     SysMqTimedreceive = 243, | ||||||
|  |     SysMqNotify = 244, | ||||||
|  |     SysMqGetsetattr = 245, | ||||||
|  |     SysKexecLoad = 246, | ||||||
|  |     SysWaitid = 247, | ||||||
|  |     SysAddKey = 248, | ||||||
|  |     SysRequestKey = 249, | ||||||
|  |     SysKeyctl = 250, | ||||||
|  |     SysIoprioSet = 251, | ||||||
|  |     SysIoprioGet = 252, | ||||||
|  |     SysInotifyInit = 253, | ||||||
|  |     SysInotifyAddWatch = 254, | ||||||
|  |     SysInotifyRmWatch = 255, | ||||||
|  |     SysMigratePages = 256, | ||||||
|  |     SysOpenat = 257, | ||||||
|  |     SysMkdirat = 258, | ||||||
|  |     SysMknodat = 259, | ||||||
|  |     SysFchownat = 260, | ||||||
|  |     SysFutimesat = 261, | ||||||
|  |     SysNewfstatat = 262, | ||||||
|  |     SysUnlinkat = 263, | ||||||
|  |     SysRenameat = 264, | ||||||
|  |     SysLinkat = 265, | ||||||
|  |     SysSymlinkat = 266, | ||||||
|  |     SysReadlinkat = 267, | ||||||
|  |     SysFchmodat = 268, | ||||||
|  |     SysFaccessat = 269, | ||||||
|  |     SysPselect6 = 270, | ||||||
|  |     SysPpoll = 271, | ||||||
|  |     SysUnshare = 272, | ||||||
|  |     SysSetRobustList = 273, | ||||||
|  |     SysGetRobustList = 274, | ||||||
|  |     SysSplice = 275, | ||||||
|  |     SysTee = 276, | ||||||
|  |     SysSyncFileRange = 277, | ||||||
|  |     SysVmsplice = 278, | ||||||
|  |     SysMovePages = 279, | ||||||
|  |     SysUtimensat = 280, | ||||||
|  |     SysEpollPwait = 281, | ||||||
|  |     SysSignalfd = 282, | ||||||
|  |     SysTimerfdCreate = 283, | ||||||
|  |     SysEventfd = 284, | ||||||
|  |     SysFallocate = 285, | ||||||
|  |     SysTimerfdSettime = 286, | ||||||
|  |     SysTimerfdGettime = 287, | ||||||
|  |     SysAccept4 = 288, | ||||||
|  |     SysSignalfd4 = 289, | ||||||
|  |     SysEventfd2 = 290, | ||||||
|  |     SysEpollCreate1 = 291, | ||||||
|  |     SysDup3 = 292, | ||||||
|  |     SysPipe2 = 293, | ||||||
|  |     SysInotifyInit1 = 294, | ||||||
|  |     SysPreadv = 295, | ||||||
|  |     SysPwritev = 296, | ||||||
|  |     SysRtTgsigqueueinfo = 297, | ||||||
|  |     SysPerfEventOpen = 298, | ||||||
|  |     SysRecvmmsg = 299, | ||||||
|  |     SysFanotifyInit = 300, | ||||||
|  |     SysFanotifyMark = 301, | ||||||
|  |     SysPrlimit64 = 302, | ||||||
|  |     SysNameToHandleAt = 303, | ||||||
|  |     SysOpenByHandleAt = 304, | ||||||
|  |     SysClockAdjtime = 305, | ||||||
|  |     SysSyncfs = 306, | ||||||
|  |     SysSendmmsg = 307, | ||||||
|  |     SysSetns = 308, | ||||||
|  |     SysGetcpu = 309, | ||||||
|  |     SysProcessVmReadv = 310, | ||||||
|  |     SysProcessVmWritev = 311, | ||||||
|  |     SysKcmp = 312, | ||||||
|  |     SysFinitModule = 313, | ||||||
|  |     SysSchedSetattr = 314, | ||||||
|  |     SysSchedGetattr = 315, | ||||||
|  |     SysRenameat2 = 316, | ||||||
|  |     SysSeccomp = 317, | ||||||
|  |     SysGetrandom = 318, | ||||||
|  |     SysMemfdCreate = 319, | ||||||
|  |     SysKexecFileLoad = 320, | ||||||
|  |     SysBpf = 321, | ||||||
|  |     SysExecveat = 322, | ||||||
|  |     SysUserfaultfd = 323, | ||||||
|  |     SysMembarrier = 324, | ||||||
|  |     SysMlock2 = 325, | ||||||
|  | 
 | ||||||
|  |     SysSpawn = 360, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl TryFrom<u32> for SyscallNum { | ||||||
|  |     type Error = error::Error; | ||||||
|  | 
 | ||||||
|  |     fn try_from(value: u32) -> Result<Self> { | ||||||
|  |         if value > 325 && value != 360 { | ||||||
|  |             return_errno!(EINVAL, "invalid syscall number"); | ||||||
|  |         } else { | ||||||
|  |             Ok(unsafe { core::mem::transmute(value as u16) }) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,7 +1,15 @@ | |||||||
|  | use super::*; | ||||||
|  | use core::convert::TryFrom; | ||||||
|  | use process::pid_t; | ||||||
| use rcore_fs::dev::TimeProvider; | use rcore_fs::dev::TimeProvider; | ||||||
| use rcore_fs::vfs::Timespec; | use rcore_fs::vfs::Timespec; | ||||||
|  | use std::time::Duration; | ||||||
|  | use std::{fmt, u64}; | ||||||
|  | use syscall::SyscallNum; | ||||||
| 
 | 
 | ||||||
| use super::*; | mod profiler; | ||||||
|  | 
 | ||||||
|  | pub use profiler::GLOBAL_PROFILER; | ||||||
| 
 | 
 | ||||||
| #[allow(non_camel_case_types)] | #[allow(non_camel_case_types)] | ||||||
| pub type time_t = i64; | pub type time_t = i64; | ||||||
| @ -18,10 +26,6 @@ pub struct timeval_t { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl timeval_t { | impl timeval_t { | ||||||
|     pub fn as_usec(&self) -> usize { |  | ||||||
|         (self.sec * 1000000 + self.usec) as usize |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     pub fn validate(&self) -> Result<()> { |     pub fn validate(&self) -> Result<()> { | ||||||
|         if self.sec >= 0 && self.usec >= 0 && self.usec < 1_000_000 { |         if self.sec >= 0 && self.usec >= 0 && self.usec < 1_000_000 { | ||||||
|             Ok(()) |             Ok(()) | ||||||
| @ -29,6 +33,10 @@ impl timeval_t { | |||||||
|             return_errno!(EINVAL, "invalid value for timeval_t"); |             return_errno!(EINVAL, "invalid value for timeval_t"); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     pub fn as_duration(&self) -> Duration { | ||||||
|  |         Duration::new(self.sec as u64, (self.usec * 1_000) as u32) | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn do_gettimeofday() -> timeval_t { | pub fn do_gettimeofday() -> timeval_t { | ||||||
| @ -55,9 +63,7 @@ pub struct timespec_t { | |||||||
| impl timespec_t { | impl timespec_t { | ||||||
|     pub fn from_raw_ptr(ptr: *const timespec_t) -> Result<timespec_t> { |     pub fn from_raw_ptr(ptr: *const timespec_t) -> Result<timespec_t> { | ||||||
|         let ts = unsafe { *ptr }; |         let ts = unsafe { *ptr }; | ||||||
|         if ts.sec < 0 || ts.nsec < 0 || ts.nsec >= 1_000_000_000 { |         ts.validate()?; | ||||||
|             return_errno!(EINVAL, "Invalid timespec fields"); |  | ||||||
|         } |  | ||||||
|         Ok(ts) |         Ok(ts) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -68,6 +74,10 @@ impl timespec_t { | |||||||
|             return_errno!(EINVAL, "invalid value for timespec_t"); |             return_errno!(EINVAL, "invalid value for timespec_t"); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     pub fn as_duration(&self) -> Duration { | ||||||
|  |         Duration::new(self.sec as u64, self.nsec as u32) | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[allow(non_camel_case_types)] | #[allow(non_camel_case_types)] | ||||||
| @ -126,6 +136,22 @@ pub fn do_nanosleep(req: ×pec_t) -> Result<()> { | |||||||
|     Ok(()) |     Ok(()) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | pub fn do_thread_getcpuclock() -> Result<timespec_t> { | ||||||
|  |     extern "C" { | ||||||
|  |         fn occlum_ocall_thread_getcpuclock(ret: *mut c_int, tp: *mut timespec_t) -> sgx_status_t; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     let mut tv: timespec_t = Default::default(); | ||||||
|  |     try_libc!({ | ||||||
|  |         let mut retval: i32 = 0; | ||||||
|  |         let status = occlum_ocall_thread_getcpuclock(&mut retval, &mut tv as *mut timespec_t); | ||||||
|  |         assert!(status == sgx_status_t::SGX_SUCCESS); | ||||||
|  |         retval | ||||||
|  |     }); | ||||||
|  |     tv.validate()?; | ||||||
|  |     Ok(tv) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // For SEFS
 | // For SEFS
 | ||||||
| pub struct OcclumTimeProvider; | pub struct OcclumTimeProvider; | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										395
									
								
								src/libos/src/time/profiler.rs
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										395
									
								
								src/libos/src/time/profiler.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,395 @@ | |||||||
|  | use super::*; | ||||||
|  | 
 | ||||||
|  | lazy_static! { | ||||||
|  |     pub static ref GLOBAL_PROFILER: SgxMutex<GlobalProfiler> = SgxMutex::new(GlobalProfiler::new()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// A profiler that can be used across threads.
 | ||||||
|  | // TODO: Use light-weight thread_local storage other than mutex
 | ||||||
|  | pub struct GlobalProfiler { | ||||||
|  |     inner: HashMap<pid_t, ThreadProfiler>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl GlobalProfiler { | ||||||
|  |     pub fn new() -> Self { | ||||||
|  |         Self { | ||||||
|  |             inner: HashMap::new(), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn thread_enter(&mut self) -> Result<()> { | ||||||
|  |         let tid = process::do_gettid(); | ||||||
|  |         if self.inner.insert(tid, ThreadProfiler::new()).is_some() { | ||||||
|  |             return_errno!( | ||||||
|  |                 EINVAL, | ||||||
|  |                 "global profiler should exit the thread before entering" | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |         self.inner.get_mut(&tid).unwrap().start() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn thread_exit(&mut self) -> Result<()> { | ||||||
|  |         // A thread exits by invoking SysExit syscall which
 | ||||||
|  |         // will never return
 | ||||||
|  |         self.syscall_exit(SyscallNum::SysExit, false); | ||||||
|  | 
 | ||||||
|  |         let tid = process::do_gettid(); | ||||||
|  |         println!("thread {} exits", tid); | ||||||
|  | 
 | ||||||
|  |         let mut exiting_profiler = self.inner.remove(&tid).ok_or_else(|| { | ||||||
|  |             errno!( | ||||||
|  |                 EINVAL, | ||||||
|  |                 "global profiler should enter a thread before exit one" | ||||||
|  |             ) | ||||||
|  |         })?; | ||||||
|  |         exiting_profiler.stop()?; | ||||||
|  |         exiting_profiler.display()?; | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn syscall_enter(&mut self, syscall_num: SyscallNum) -> Result<()> { | ||||||
|  |         let tid = process::do_gettid(); | ||||||
|  |         let mut prof = self.inner.get_mut(&tid).unwrap(); | ||||||
|  |         prof.syscall_enter(syscall_num) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn syscall_exit(&mut self, syscall_num: SyscallNum, is_err: bool) -> Result<()> { | ||||||
|  |         let tid = process::do_gettid(); | ||||||
|  |         let mut prof = self.inner.get_mut(&tid).unwrap(); | ||||||
|  |         prof.syscall_exit(syscall_num, is_err) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | /// A profiler used inside a thread.
 | ||||||
|  | // TODO: add support for exception
 | ||||||
|  | #[derive(Clone)] | ||||||
|  | pub struct ThreadProfiler { | ||||||
|  |     syscall_data: HashMap<SyscallNum, PerfEntry>, | ||||||
|  |     start_time: ProfileTime, | ||||||
|  |     status: Status, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl ThreadProfiler { | ||||||
|  |     pub fn new() -> Self { | ||||||
|  |         Self { | ||||||
|  |             syscall_data: HashMap::new(), | ||||||
|  |             start_time: ProfileTime::TwoTimes { | ||||||
|  |                 real: Duration::new(0, 0), | ||||||
|  |                 cpu: Duration::new(0, 0), | ||||||
|  |             }, | ||||||
|  |             status: Status::Stopped(TimeSummary::new( | ||||||
|  |                 Duration::new(0, 0), | ||||||
|  |                 Duration::new(0, 0), | ||||||
|  |                 Duration::new(0, 0), | ||||||
|  |             )), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn start(&mut self) -> Result<()> { | ||||||
|  |         match self.status { | ||||||
|  |             Status::Stopped(..) => { | ||||||
|  |                 self.status = Status::Running; | ||||||
|  |                 self.start_time.update() | ||||||
|  |             } | ||||||
|  |             _ => return_errno!( | ||||||
|  |                 EINVAL, | ||||||
|  |                 "thread profiler can only be started in stopped status" | ||||||
|  |             ), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn stop(&mut self) -> Result<()> { | ||||||
|  |         if self.status != Status::Running { | ||||||
|  |             error!("wrong status is {:?}", self.status); | ||||||
|  |             return_errno!(EINVAL, "fail to stop thread profiler"); | ||||||
|  |         } | ||||||
|  |         let real = time::do_gettimeofday().as_duration() - self.start_time.get_realtime().unwrap(); | ||||||
|  | 
 | ||||||
|  |         let total_cputime = | ||||||
|  |             time::do_thread_getcpuclock()?.as_duration() - self.start_time.get_cputime().unwrap(); | ||||||
|  |         let sys = self.get_syscall_total_time()?; | ||||||
|  |         let usr = total_cputime - sys; | ||||||
|  |         self.status = Status::Stopped(TimeSummary::new(real, usr, sys)); | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn syscall_enter(&mut self, syscall_num: SyscallNum) -> Result<()> { | ||||||
|  |         match self.status { | ||||||
|  |             Status::Running => { | ||||||
|  |                 let mut cur_time = ProfileTime::CpuTime(Default::default()); | ||||||
|  |                 cur_time.update()?; | ||||||
|  |                 self.status = Status::InSyscall { | ||||||
|  |                     start_cpu: cur_time, | ||||||
|  |                     num: syscall_num, | ||||||
|  |                 }; | ||||||
|  |                 self.syscall_data | ||||||
|  |                     .entry(syscall_num) | ||||||
|  |                     .or_insert(PerfEntry::new()); | ||||||
|  |                 Ok(()) | ||||||
|  |             } | ||||||
|  |             _ => return_errno!( | ||||||
|  |                 EINVAL, | ||||||
|  |                 "threa profiler should be started before entering syscall" | ||||||
|  |             ), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn syscall_exit(&mut self, syscall_num: SyscallNum, is_err: bool) -> Result<()> { | ||||||
|  |         match self.status { | ||||||
|  |             Status::InSyscall { start_cpu, num } => { | ||||||
|  |                 if syscall_num != num { | ||||||
|  |                     return_errno!(EINVAL, "syscall number mismatches"); | ||||||
|  |                 } | ||||||
|  |                 self.status = Status::Running; | ||||||
|  |                 let syscall_cpu_time = | ||||||
|  |                     time::do_thread_getcpuclock()?.as_duration() - start_cpu.get_cputime().unwrap(); | ||||||
|  | 
 | ||||||
|  |                 self.syscall_data.entry(num).and_modify(|e| { | ||||||
|  |                     e.update(syscall_cpu_time, is_err) | ||||||
|  |                         .expect("fail to update syscall data") | ||||||
|  |                 }); | ||||||
|  |                 Ok(()) | ||||||
|  |             } | ||||||
|  |             _ => return_errno!( | ||||||
|  |                 EINVAL, | ||||||
|  |                 "thread profiler should be in one syscall before exiting the syscall" | ||||||
|  |             ), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn get_syscall_total_time(&self) -> Result<Duration> { | ||||||
|  |         Ok(self.get_syscall_total()?.0) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn get_syscall_total(&self) -> Result<(Duration, u32, u32)> { | ||||||
|  |         let mut total_time: Duration = Duration::new(0, 0); | ||||||
|  |         let mut total_calls: u32 = 0; | ||||||
|  |         let mut total_errors: u32 = 0; | ||||||
|  |         for entry in self.syscall_data.values() { | ||||||
|  |             total_time += entry.get_total_time(); | ||||||
|  |             total_calls = entry | ||||||
|  |                 .get_calls() | ||||||
|  |                 .checked_add(total_calls) | ||||||
|  |                 .ok_or_else(|| errno!(EOVERFLOW, "total calls overflow"))?; | ||||||
|  |             total_errors += entry.get_errors(); | ||||||
|  |         } | ||||||
|  |         Ok((total_time, total_calls, total_errors)) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn display(&self) -> Result<()> { | ||||||
|  |         match self.status { | ||||||
|  |             Status::Stopped(report) => { | ||||||
|  |                 // Pretty-print the Debug formatting report of the profiled thread
 | ||||||
|  |                 println!("{:#?}", report); | ||||||
|  |                 // Print the syscall statistics of the profiled thread
 | ||||||
|  |                 self.display_syscall_stat() | ||||||
|  |             } | ||||||
|  |             _ => return_errno!(EINVAL, "thread profiler can report only in stopped status"), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /// Print the syscall statistics of the profiled thread.
 | ||||||
|  |     ///
 | ||||||
|  |     /// The statistics consist of:
 | ||||||
|  |     /// syscall number, the corresponding percentage of the aggregate time in all the syscalls,
 | ||||||
|  |     /// the aggregate time, average execution time of a call, aggregate calls, aggregate errors,
 | ||||||
|  |     /// the shortest and longest execution time of the syscall.
 | ||||||
|  |     /// A piece of the output is:
 | ||||||
|  |     /// syscall             % time     seconds     us/call     calls    errors range(us)
 | ||||||
|  |     /// ------------------- ------ ----------- ----------- --------- --------- -----------
 | ||||||
|  |     /// SysWritev             0.40    0.000131          26         5         0 [12, 47]
 | ||||||
|  |     /// SysMprotect           0.03    0.000009           4         2         0 [4, 4]
 | ||||||
|  |     /// ------------------- ------ ----------- ----------- --------- --------- -----------
 | ||||||
|  |     fn display_syscall_stat(&self) -> Result<()> { | ||||||
|  |         println!( | ||||||
|  |             "{:<19} {:>6} {:>11} {:>11} {:>9} {:>9} {}", | ||||||
|  |             "syscall", "% time", "seconds", "us/call", "calls", "errors", "range(us)", | ||||||
|  |         ); | ||||||
|  |         println!( | ||||||
|  |             "{:-<19} {:-<6} {:-<11} {:-<11} {:-<9} {:-<9} {:-<11}", | ||||||
|  |             "", "", "", "", "", "", "" | ||||||
|  |         ); | ||||||
|  | 
 | ||||||
|  |         let (total_time, total_calls, total_errors) = self.get_syscall_total()?; | ||||||
|  |         let mut syscall_data_ref: Vec<(&SyscallNum, &PerfEntry)> = | ||||||
|  |             self.syscall_data.iter().collect(); | ||||||
|  |         syscall_data_ref.sort_by(|(_, entry_a), (_, entry_b)| { | ||||||
|  |             entry_b.get_total_time().cmp(&(entry_a.get_total_time())) | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         for (syscall_num, entry) in syscall_data_ref { | ||||||
|  |             let time_percentage = | ||||||
|  |                 entry.get_total_time().as_secs_f64() / total_time.as_secs_f64() * 100_f64; | ||||||
|  |             println!( | ||||||
|  |                 "{:<19} {:>6.2} {:?}", | ||||||
|  |                 format!("{:?}", syscall_num), | ||||||
|  |                 time_percentage, | ||||||
|  |                 entry, | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         println!( | ||||||
|  |             "{:-<19} {:-<6} {:-<11} {:-<11} {:-<9} {:-<9} {:-<11}", | ||||||
|  |             "", "", "", "", "", "", "" | ||||||
|  |         ); | ||||||
|  | 
 | ||||||
|  |         println!( | ||||||
|  |             "{} {:>20} {:>11.6} {:>21} {:>9}", | ||||||
|  |             "total", | ||||||
|  |             "100", | ||||||
|  |             total_time.as_secs_f64(), | ||||||
|  |             total_calls, | ||||||
|  |             total_errors, | ||||||
|  |         ); | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Copy, Clone)] | ||||||
|  | struct PerfEntry { | ||||||
|  |     calls: u32, | ||||||
|  |     total_time: Duration, | ||||||
|  |     peak: Duration, | ||||||
|  |     bottom: Duration, | ||||||
|  |     errors: u32, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl PerfEntry { | ||||||
|  |     fn new() -> Self { | ||||||
|  |         Self { | ||||||
|  |             calls: 0, | ||||||
|  |             total_time: Duration::new(0, 0), | ||||||
|  |             peak: Duration::new(0, 0), | ||||||
|  |             bottom: Duration::new(u64::MAX, 1_000_000_000 - 1), | ||||||
|  |             errors: 0, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn update(&mut self, time: Duration, is_err: bool) -> Result<()> { | ||||||
|  |         self.calls = self | ||||||
|  |             .calls | ||||||
|  |             .checked_add(1) | ||||||
|  |             .ok_or_else(|| errno!(EOVERFLOW, "single syscallduration addition overflow"))?; | ||||||
|  |         self.total_time += time; | ||||||
|  | 
 | ||||||
|  |         if time > self.peak { | ||||||
|  |             self.peak = time; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if time < self.bottom { | ||||||
|  |             self.bottom = time; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if is_err { | ||||||
|  |             self.errors += 1; | ||||||
|  |         } | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn get_average(&self) -> Duration { | ||||||
|  |         if self.calls == 0 { | ||||||
|  |             Duration::new(0, 0) | ||||||
|  |         } else { | ||||||
|  |             self.total_time / self.calls | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn get_calls(&self) -> u32 { | ||||||
|  |         self.calls | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn get_total_time(&self) -> Duration { | ||||||
|  |         self.total_time | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn get_errors(&self) -> u32 { | ||||||
|  |         self.errors | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// Used for the display of ThreadProfiler.
 | ||||||
|  | /// The total execution time in secs, average execution time in microseconds,
 | ||||||
|  | /// total calls, total errors, the shortest and longest execution time.
 | ||||||
|  | /// The output looks like:
 | ||||||
|  | /// 0.000009           4         2         0 [4, 4]
 | ||||||
|  | impl fmt::Debug for PerfEntry { | ||||||
|  |     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||||
|  |         write!( | ||||||
|  |             f, | ||||||
|  |             "{:>11.6} {:>11} {:>9} {:>9} [{}, {}]", | ||||||
|  |             self.total_time.as_secs_f64(), | ||||||
|  |             self.get_average().as_micros(), | ||||||
|  |             self.calls, | ||||||
|  |             self.errors, | ||||||
|  |             self.bottom.as_micros(), | ||||||
|  |             self.peak.as_micros() | ||||||
|  |         ) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Copy, Clone, Debug, Eq, PartialEq)] | ||||||
|  | enum ProfileTime { | ||||||
|  |     RealTime(Duration), | ||||||
|  |     CpuTime(Duration), | ||||||
|  |     TwoTimes { real: Duration, cpu: Duration }, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl ProfileTime { | ||||||
|  |     fn get_realtime(&self) -> Option<Duration> { | ||||||
|  |         match *self { | ||||||
|  |             ProfileTime::RealTime(t) => Some(t), | ||||||
|  |             ProfileTime::CpuTime(t) => None, | ||||||
|  |             ProfileTime::TwoTimes { real, cpu } => Some(real), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn get_cputime(&self) -> Option<Duration> { | ||||||
|  |         match *self { | ||||||
|  |             ProfileTime::RealTime(t) => None, | ||||||
|  |             ProfileTime::CpuTime(t) => Some(t), | ||||||
|  |             ProfileTime::TwoTimes { real, cpu } => Some(cpu), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn update(&mut self) -> Result<()> { | ||||||
|  |         match self { | ||||||
|  |             ProfileTime::RealTime(ref mut t) => *t = time::do_gettimeofday().as_duration(), | ||||||
|  |             ProfileTime::CpuTime(ref mut t) => *t = time::do_thread_getcpuclock()?.as_duration(), | ||||||
|  |             ProfileTime::TwoTimes { | ||||||
|  |                 ref mut real, | ||||||
|  |                 ref mut cpu, | ||||||
|  |             } => { | ||||||
|  |                 *real = time::do_gettimeofday().as_duration(); | ||||||
|  |                 *cpu = time::do_thread_getcpuclock()?.as_duration(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// The timing statistics about one thread.
 | ||||||
|  | /// These statistics consist of:
 | ||||||
|  | /// (i) the elapsed real time between invocation and termination
 | ||||||
|  | /// (ii) the CPU time running in user space
 | ||||||
|  | /// (iii) the CPU time running in libos
 | ||||||
|  | #[derive(Copy, Clone, Debug, Eq, PartialEq)] | ||||||
|  | struct TimeSummary { | ||||||
|  |     real: Duration, | ||||||
|  |     usr: Duration, | ||||||
|  |     sys: Duration, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl TimeSummary { | ||||||
|  |     fn new(real: Duration, usr: Duration, sys: Duration) -> Self { | ||||||
|  |         Self { real, usr, sys } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Clone, Debug, Eq, PartialEq)] | ||||||
|  | enum Status { | ||||||
|  |     Running, | ||||||
|  |     Stopped(TimeSummary), | ||||||
|  |     InSyscall { | ||||||
|  |         start_cpu: ProfileTime, | ||||||
|  |         num: SyscallNum, | ||||||
|  |     }, | ||||||
|  | } | ||||||
| @ -1,3 +1,4 @@ | |||||||
|  | #include <pthread.h> | ||||||
| #include <sys/time.h> | #include <sys/time.h> | ||||||
| #include "ocalls.h" | #include "ocalls.h" | ||||||
| 
 | 
 | ||||||
| @ -12,3 +13,14 @@ void occlum_ocall_clock_gettime(int clockid, struct timespec *tp) { | |||||||
| void occlum_ocall_nanosleep(const struct timespec* req) { | void occlum_ocall_nanosleep(const struct timespec* req) { | ||||||
|     nanosleep(req, NULL); |     nanosleep(req, NULL); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | int occlum_ocall_thread_getcpuclock(struct timespec *tp) { | ||||||
|  |     clockid_t thread_clock_id; | ||||||
|  |     int ret = pthread_getcpuclockid(pthread_self(), &thread_clock_id); | ||||||
|  |     if(ret != 0) { | ||||||
|  |        PAL_ERROR("failed to get clock id"); | ||||||
|  |        return -1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return clock_gettime(thread_clock_id, tp); | ||||||
|  | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user