Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F140972115
D1465.id4419.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D1465.id4419.diff
View Options
Index: sys/compat/linux/linux_time.c
===================================================================
--- sys/compat/linux/linux_time.c
+++ sys/compat/linux/linux_time.c
@@ -39,8 +39,11 @@
#include <sys/param.h>
#include <sys/kernel.h>
+#include <sys/lock.h>
#include <sys/ucred.h>
#include <sys/mount.h>
+#include <sys/mutex.h>
+#include <sys/resourcevar.h>
#include <sys/sdt.h>
#include <sys/signal.h>
#include <sys/stdint.h>
@@ -59,7 +62,7 @@
#endif
#include <compat/linux/linux_dtrace.h>
-#include <compat/linux/linux_misc.h>
+#include <compat/linux/linux_timer.h>
/* DTrace init */
LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
@@ -157,6 +160,20 @@
LIN_SDT_PROBE2(time, linux_to_native_clockid, entry, n, l);
+ if (l < 0) {
+ /* cpu-clock */
+ if ((l & LINUX_CLOCKFD_MASK) == LINUX_CLOCKFD)
+ return (EINVAL);
+ if (LINUX_CPUCLOCK_WHICH(l) >= LINUX_CPUCLOCK_MAX)
+ return (EINVAL);
+
+ if (LINUX_CPUCLOCK_PERTHREAD(l))
+ *n = CLOCK_THREAD_CPUTIME_ID;
+ else
+ *n = CLOCK_PROCESS_CPUTIME_ID;
+ return (0);
+ }
+
switch (l) {
case LINUX_CLOCK_REALTIME:
*n = CLOCK_REALTIME;
@@ -164,21 +181,27 @@
case LINUX_CLOCK_MONOTONIC:
*n = CLOCK_MONOTONIC;
break;
- case LINUX_CLOCK_PROCESS_CPUTIME_ID:
- case LINUX_CLOCK_THREAD_CPUTIME_ID:
- case LINUX_CLOCK_REALTIME_HR:
- case LINUX_CLOCK_MONOTONIC_HR:
+ case LINUX_CLOCK_REALTIME_COARSE:
+ *n = CLOCK_REALTIME_FAST;
+ break;
+ case LINUX_CLOCK_MONOTONIC_COARSE:
+ *n = CLOCK_MONOTONIC_FAST;
+ break;
+ case LINUX_CLOCK_MONOTONIC_RAW:
+ case LINUX_CLOCK_BOOTTIME:
+ case LINUX_CLOCK_REALTIME_ALARM:
+ case LINUX_CLOCK_BOOTTIME_ALARM:
+ case LINUX_CLOCK_SGI_CYCLE:
+ case LINUX_CLOCK_TAI:
LIN_SDT_PROBE1(time, linux_to_native_clockid,
unsupported_clockid, l);
LIN_SDT_PROBE1(time, linux_to_native_clockid, return, EINVAL);
return (EINVAL);
- break;
default:
LIN_SDT_PROBE1(time, linux_to_native_clockid,
unknown_clockid, l);
LIN_SDT_PROBE1(time, linux_to_native_clockid, return, EINVAL);
return (EINVAL);
- break;
}
LIN_SDT_PROBE1(time, linux_to_native_clockid, return, 0);
@@ -189,9 +212,14 @@
linux_clock_gettime(struct thread *td, struct linux_clock_gettime_args *args)
{
struct l_timespec lts;
- int error;
- clockid_t nwhich = 0; /* XXX: GCC */
struct timespec tp;
+ struct rusage ru;
+ struct thread *targettd;
+ struct proc *p;
+ int error, clockwhich;
+ clockid_t nwhich = 0; /* XXX: GCC */
+ pid_t pid;
+ lwpid_t tid;
LIN_SDT_PROBE2(time, linux_clock_gettime, entry, args->which, args->tp);
@@ -202,7 +230,101 @@
LIN_SDT_PROBE1(time, linux_clock_gettime, return, error);
return (error);
}
- error = kern_clock_gettime(td, nwhich, &tp);
+
+ switch (nwhich) {
+ case CLOCK_PROCESS_CPUTIME_ID:
+ clockwhich = LINUX_CPUCLOCK_WHICH(args->which);
+ pid = LINUX_CPUCLOCK_ID(args->which);
+ if (pid == 0) {
+ targettd = td;
+ p = td->td_proc;
+ PROC_LOCK(p);
+ } else {
+ error = pget(pid, PGET_CANSEE, &p);
+ if (error != 0)
+ return (EINVAL);
+ }
+ switch (clockwhich) {
+ case LINUX_CPUCLOCK_PROF:
+ PROC_STATLOCK(p);
+ calcru(p, &ru.ru_utime, &ru.ru_stime);
+ PROC_STATUNLOCK(p);
+ PROC_UNLOCK(p);
+ timevaladd(&ru.ru_utime, &ru.ru_stime);
+ TIMEVAL_TO_TIMESPEC(&ru.ru_utime, &tp);
+ break;
+ case LINUX_CPUCLOCK_VIRT:
+ PROC_STATLOCK(p);
+ calcru(p, &ru.ru_utime, &ru.ru_stime);
+ PROC_STATUNLOCK(p);
+ PROC_UNLOCK(p);
+ TIMEVAL_TO_TIMESPEC(&ru.ru_utime, &tp);
+ break;
+ case LINUX_CPUCLOCK_SCHED:
+ PROC_UNLOCK(p);
+ error = kern_clock_getcpuclockid2(td, pid,
+ CPUCLOCK_WHICH_PID, &nwhich);
+ if (error != 0)
+ return (EINVAL);
+ error = kern_clock_gettime(td, nwhich, &tp);
+ break;
+ default:
+ PROC_UNLOCK(p);
+ return (EINVAL);
+ }
+
+ break;
+
+ case CLOCK_THREAD_CPUTIME_ID:
+ clockwhich = LINUX_CPUCLOCK_WHICH(args->which);
+ p = td->td_proc;
+ tid = LINUX_CPUCLOCK_ID(args->which);
+ if (tid == 0) {
+ targettd = td;
+ PROC_LOCK(p);
+ } else {
+ targettd = tdfind(tid, p->p_pid);
+ if (targettd == NULL)
+ return (EINVAL);
+ }
+ switch (clockwhich) {
+ case LINUX_CPUCLOCK_PROF:
+ PROC_STATLOCK(p);
+ thread_lock(targettd);
+ rufetchtd(targettd, &ru);
+ thread_unlock(targettd);
+ PROC_STATUNLOCK(p);
+ PROC_UNLOCK(p);
+ timevaladd(&ru.ru_utime, &ru.ru_stime);
+ TIMEVAL_TO_TIMESPEC(&ru.ru_utime, &tp);
+ break;
+ case LINUX_CPUCLOCK_VIRT:
+ PROC_STATLOCK(p);
+ thread_lock(targettd);
+ rufetchtd(targettd, &ru);
+ thread_unlock(targettd);
+ PROC_STATUNLOCK(p);
+ PROC_UNLOCK(p);
+ TIMEVAL_TO_TIMESPEC(&ru.ru_utime, &tp);
+ break;
+ case LINUX_CPUCLOCK_SCHED:
+ error = kern_clock_getcpuclockid2(td, tid,
+ CPUCLOCK_WHICH_TID, &nwhich);
+ PROC_UNLOCK(p);
+ if (error != 0)
+ return (EINVAL);
+ error = kern_clock_gettime(td, nwhich, &tp);
+ break;
+ default:
+ PROC_UNLOCK(p);
+ return (EINVAL);
+ }
+ break;
+
+ default:
+ error = kern_clock_gettime(td, nwhich, &tp);
+ break;
+ }
if (error != 0) {
LIN_SDT_PROBE1(time, linux_clock_gettime, gettime_error, error);
LIN_SDT_PROBE1(time, linux_clock_gettime, return, error);
@@ -260,19 +382,16 @@
int
linux_clock_getres(struct thread *td, struct linux_clock_getres_args *args)
{
+ struct proc *p;
struct timespec ts;
struct l_timespec lts;
- int error;
+ int error, clockwhich;
clockid_t nwhich = 0; /* XXX: GCC */
+ pid_t pid;
+ lwpid_t tid;
LIN_SDT_PROBE2(time, linux_clock_getres, entry, args->which, args->tp);
- if (args->tp == NULL) {
- LIN_SDT_PROBE0(time, linux_clock_getres, nullcall);
- LIN_SDT_PROBE1(time, linux_clock_getres, return, 0);
- return (0);
- }
-
error = linux_to_native_clockid(&nwhich, args->which);
if (error != 0) {
LIN_SDT_PROBE1(time, linux_clock_getres, conversion_error,
@@ -280,6 +399,55 @@
LIN_SDT_PROBE1(time, linux_clock_getres, return, error);
return (error);
}
+
+ switch (nwhich) {
+ case CLOCK_THREAD_CPUTIME_ID:
+ tid = LINUX_CPUCLOCK_ID(args->which);
+ if (tid != 0) {
+ p = td->td_proc;
+ if (tdfind(tid, p->p_pid) == NULL)
+ return (ESRCH);
+ PROC_UNLOCK(p);
+ }
+ break;
+ case CLOCK_PROCESS_CPUTIME_ID:
+ pid = LINUX_CPUCLOCK_ID(args->which);
+ if (pid != 0) {
+ error = pget(pid, PGET_CANSEE, &p);
+ if (error != 0)
+ return (EINVAL);
+ PROC_UNLOCK(p);
+ }
+ break;
+ }
+
+ if (args->tp == NULL) {
+ LIN_SDT_PROBE0(time, linux_clock_getres, nullcall);
+ LIN_SDT_PROBE1(time, linux_clock_getres, return, 0);
+ return (0);
+ }
+
+ switch (nwhich) {
+ case CLOCK_THREAD_CPUTIME_ID:
+ case CLOCK_PROCESS_CPUTIME_ID:
+ clockwhich = LINUX_CPUCLOCK_WHICH(args->which);
+ switch (clockwhich) {
+ case LINUX_CPUCLOCK_PROF:
+ nwhich = CLOCK_PROF;
+ break;
+ case LINUX_CPUCLOCK_VIRT:
+ nwhich = CLOCK_VIRTUAL;
+ break;
+ case LINUX_CPUCLOCK_SCHED:
+ break;
+ default:
+ return (EINVAL);
+ }
+ break;
+
+ default:
+ break;
+ }
error = kern_clock_getres(td, nwhich, &ts);
if (error != 0) {
LIN_SDT_PROBE1(time, linux_clock_getres, getres_error, error);
Index: sys/compat/linux/linux_timer.h
===================================================================
--- sys/compat/linux/linux_timer.h
+++ sys/compat/linux/linux_timer.h
@@ -56,6 +56,23 @@
#define LINUX_CLOCK_SGI_CYCLE 10
#define LINUX_CLOCK_TAI 11
+#define LINUX_CPUCLOCK_PERTHREAD_MASK 4
+#define LINUX_CPUCLOCK_MASK 3
+#define LINUX_CPUCLOCK_WHICH(clock) \
+ ((clock) & (clockid_t) LINUX_CPUCLOCK_MASK)
+#define LINUX_CPUCLOCK_PROF 0
+#define LINUX_CPUCLOCK_VIRT 1
+#define LINUX_CPUCLOCK_SCHED 2
+#define LINUX_CPUCLOCK_MAX 3
+#define LINUX_CLOCKFD LINUX_CPUCLOCK_MAX
+#define LINUX_CLOCKFD_MASK \
+ (LINUX_CPUCLOCK_PERTHREAD_MASK|LINUX_CPUCLOCK_MASK)
+
+#define LINUX_CPUCLOCK_ID(clock) ((pid_t) ~((clock) >> 3))
+#define LINUX_CPUCLOCK_PERTHREAD(clock) \
+ (((clock) & (clockid_t) LINUX_CPUCLOCK_PERTHREAD_MASK) != 0)
+
+
#define L_SIGEV_SIGNAL 0
#define L_SIGEV_NONE 1
#define L_SIGEV_THREAD 2
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Dec 31, 6:40 AM (3 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27404706
Default Alt Text
D1465.id4419.diff (7 KB)
Attached To
Mode
D1465: Linuxulator. Clock mappings.
Attached
Detach File
Event Timeline
Log In to Comment