Print this page
OS-5804 lxbrand needs support for CLOCK_*_CPUTIME_ID timers
   1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2016 Joyent, Inc.
  14  */
  15 
  16 /*
  17  * The illumos kernel provides two clock backends: CLOCK_REALTIME, the
  18  * adjustable system wall clock; and CLOCK_HIGHRES, the monotonically
  19  * increasing time source that is not subject to drift or adjustment.  By
  20  * contrast, the Linux kernel is furnished with an overabundance of narrowly
  21  * differentiated clock types.
  22  *
  23  * Fortunately, most of the commonly used Linux clock types are either similar
  24  * enough to the native clock backends that they can be directly mapped, or
  25  * represent queries to the per-process and per-LWP microstate counters.
  26  *








  27  * CLOCK_BOOTTIME is identical to CLOCK_MONOTONIC, except that it takes into
  28  * account time that the system is suspended. Since that is uninteresting to
  29  * us, we treat it the same.
  30  */
  31 
  32 #include <sys/time.h>
  33 #include <sys/systm.h>
  34 #include <sys/cmn_err.h>
  35 #include <sys/brand.h>
  36 #include <sys/lx_brand.h>
  37 #include <sys/lx_impl.h>
  38 #include <lx_signum.h>
  39 
  40 /*
  41  * From "uts/common/os/timer.c":
  42  */
  43 extern int clock_settime(clockid_t, timespec_t *);
  44 extern int clock_gettime(clockid_t, timespec_t *);
  45 extern int clock_getres(clockid_t, timespec_t *);
  46 extern int nanosleep(timespec_t *, timespec_t *);


  66         int tz_dsttime;         /* type of dst correction */
  67 };
  68 
  69 /*
  70  * Use the native clock_* system call implementation, but with a translated
  71  * clock identifier:
  72  */
  73 #define NATIVE(ntv_id)                                                  \
  74         { ntv_id, clock_getres, clock_gettime, clock_settime }
  75 
  76 /*
  77  * This backend is not supported, so we provide an emulation handler:
  78  */
  79 #define EMUL(ntv_id)                                                    \
  80         { ntv_id, lx_emul_clock_getres, lx_emul_clock_gettime,          \
  81             lx_emul_clock_settime }
  82 
  83 static lx_clock_backend_t lx_clock_backends[] = {
  84         NATIVE(CLOCK_REALTIME),         /* LX_CLOCK_REALTIME */
  85         NATIVE(CLOCK_HIGHRES),          /* LX_CLOCK_MONOTONIC */
  86         EMUL(CLOCK_PROCESS_CPUTIME_ID), /* LX_CLOCK_PROCESS_CPUTIME_ID */
  87         EMUL(CLOCK_THREAD_CPUTIME_ID),  /* LX_CLOCK_THREAD_CPUTIME_ID */
  88         NATIVE(CLOCK_HIGHRES),          /* LX_CLOCK_MONOTONIC_RAW */
  89         NATIVE(CLOCK_REALTIME),         /* LX_CLOCK_REALTIME_COARSE */
  90         NATIVE(CLOCK_HIGHRES),          /* LX_CLOCK_MONOTONIC_COARSE */
  91         NATIVE(CLOCK_HIGHRES)           /* LX_CLOCK_BOOTTIME */
  92 };
  93 
  94 #define LX_CLOCK_MAX \
  95         (sizeof (lx_clock_backends) / sizeof (lx_clock_backends[0]))
  96 #define LX_CLOCK_BACKEND(clk) (((clk) < LX_CLOCK_MAX && (clk) >= 0) ? \
  97         &lx_clock_backends[(clk)] : NULL)
  98 
  99 /*
 100  * Linux defines the size of the sigevent structure to be 64 bytes.  In order
 101  * to meet that definition, the trailing union includes a member which pads it
 102  * out to the desired length for the given architecture.
 103  */
 104 #define LX_SIGEV_PAD_SIZE       ((64 - \
 105         (sizeof (int) * 2 + sizeof (union sigval))) / sizeof (int))
 106 
 107 typedef struct {


   1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2020 Joyent, Inc.
  14  */
  15 
  16 /*
  17  * The illumos kernel provides two clock backends: CLOCK_REALTIME, the
  18  * adjustable system wall clock; and CLOCK_HIGHRES, the monotonically
  19  * increasing time source that is not subject to drift or adjustment.  By
  20  * contrast, the Linux kernel is furnished with an overabundance of narrowly
  21  * differentiated clock types.
  22  *
  23  * Fortunately, most of the commonly used Linux clock types are similar
  24  * enough to the native clock backends that they can be directly mapped.

  25  *
  26  * Unfortunately, while CLOCK_{THREAD,PROCESS}_CPUTIME_ID are *somewhat*
  27  * implemented in the main illumos kernel as itimers (see setitimer(2)), we
  28  * would need to entirely bringup of CLOCK_{THREAD,PROCESS}_CPUTIME_ID to
  29  * implement timer_create() and friends.  For now, we opt to map it to
  30  * CLOCK_HIGHRES for timer_create() and friends, but continue to emulate
  31  * more-accurate queries to per-process or per-LWP microstate accounting for
  32  * getres, gettime, or settime.
  33  *
  34  * CLOCK_BOOTTIME is identical to CLOCK_MONOTONIC, except that it takes into
  35  * account time that the system is suspended. Since that is uninteresting to
  36  * us, we treat it the same.
  37  */
  38 
  39 #include <sys/time.h>
  40 #include <sys/systm.h>
  41 #include <sys/cmn_err.h>
  42 #include <sys/brand.h>
  43 #include <sys/lx_brand.h>
  44 #include <sys/lx_impl.h>
  45 #include <lx_signum.h>
  46 
  47 /*
  48  * From "uts/common/os/timer.c":
  49  */
  50 extern int clock_settime(clockid_t, timespec_t *);
  51 extern int clock_gettime(clockid_t, timespec_t *);
  52 extern int clock_getres(clockid_t, timespec_t *);
  53 extern int nanosleep(timespec_t *, timespec_t *);


  73         int tz_dsttime;         /* type of dst correction */
  74 };
  75 
  76 /*
  77  * Use the native clock_* system call implementation, but with a translated
  78  * clock identifier:
  79  */
  80 #define NATIVE(ntv_id)                                                  \
  81         { ntv_id, clock_getres, clock_gettime, clock_settime }
  82 
  83 /*
  84  * This backend is not supported, so we provide an emulation handler:
  85  */
  86 #define EMUL(ntv_id)                                                    \
  87         { ntv_id, lx_emul_clock_getres, lx_emul_clock_gettime,          \
  88             lx_emul_clock_settime }
  89 
  90 static lx_clock_backend_t lx_clock_backends[] = {
  91         NATIVE(CLOCK_REALTIME),         /* LX_CLOCK_REALTIME */
  92         NATIVE(CLOCK_HIGHRES),          /* LX_CLOCK_MONOTONIC */
  93         EMUL(CLOCK_HIGHRES),            /* LX_CLOCK_PROCESS_CPUTIME_ID */
  94         EMUL(CLOCK_HIGHRES),            /* LX_CLOCK_THREAD_CPUTIME_ID */
  95         NATIVE(CLOCK_HIGHRES),          /* LX_CLOCK_MONOTONIC_RAW */
  96         NATIVE(CLOCK_REALTIME),         /* LX_CLOCK_REALTIME_COARSE */
  97         NATIVE(CLOCK_HIGHRES),          /* LX_CLOCK_MONOTONIC_COARSE */
  98         NATIVE(CLOCK_HIGHRES)           /* LX_CLOCK_BOOTTIME */
  99 };
 100 
 101 #define LX_CLOCK_MAX \
 102         (sizeof (lx_clock_backends) / sizeof (lx_clock_backends[0]))
 103 #define LX_CLOCK_BACKEND(clk) (((clk) < LX_CLOCK_MAX && (clk) >= 0) ? \
 104         &lx_clock_backends[(clk)] : NULL)
 105 
 106 /*
 107  * Linux defines the size of the sigevent structure to be 64 bytes.  In order
 108  * to meet that definition, the trailing union includes a member which pads it
 109  * out to the desired length for the given architecture.
 110  */
 111 #define LX_SIGEV_PAD_SIZE       ((64 - \
 112         (sizeof (int) * 2 + sizeof (union sigval))) / sizeof (int))
 113 
 114 typedef struct {