The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/openzfs/include/os/freebsd/spl/sys/condvar.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
    3  * Copyright (c) 2013 iXsystems, Inc.
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  *
   27  * $FreeBSD$
   28  */
   29 
   30 #ifndef _OPENSOLARIS_SYS_CONDVAR_H_
   31 #define _OPENSOLARIS_SYS_CONDVAR_H_
   32 
   33 #include <sys/param.h>
   34 #include <sys/systm.h>
   35 
   36 #include <sys/spl_condvar.h>
   37 #include <sys/mutex.h>
   38 #include <sys/time.h>
   39 #include <sys/errno.h>
   40 
   41 /*
   42  * cv_timedwait() is similar to cv_wait() except that it additionally expects
   43  * a timeout value specified in ticks.  When woken by cv_signal() or
   44  * cv_broadcast() it returns 1, otherwise when the timeout is reached -1 is
   45  * returned.
   46  *
   47  * cv_timedwait_sig() behaves the same as cv_timedwait() but blocks
   48  * interruptibly and can be woken by a signal (EINTR, ERESTART).  When
   49  * this occurs 0 is returned.
   50  *
   51  * cv_timedwait_io() and cv_timedwait_sig_io() are variants of cv_timedwait()
   52  * and cv_timedwait_sig() which should be used when waiting for outstanding
   53  * IO to complete.  They are responsible for updating the iowait accounting
   54  * when this is supported by the platform.
   55  *
   56  * cv_timedwait_hires() and cv_timedwait_sig_hires() are high resolution
   57  * versions of cv_timedwait() and cv_timedwait_sig().  They expect the timeout
   58  * to be specified as a hrtime_t allowing for timeouts of less than a tick.
   59  *
   60  * N.B. The return values differ slightly from the illumos implementation
   61  * which returns the time remaining, instead of 1, when woken.  They both
   62  * return -1 on timeout. Consumers which need to know the time remaining
   63  * are responsible for tracking it themselves.
   64  */
   65 
   66 static __inline sbintime_t
   67 zfs_nstosbt(int64_t _ns)
   68 {
   69         sbintime_t sb = 0;
   70 
   71 #ifdef KASSERT
   72         KASSERT(_ns >= 0, ("Negative values illegal for nstosbt: %jd", _ns));
   73 #endif
   74         if (_ns >= SBT_1S) {
   75                 sb = (_ns / 1000000000) * SBT_1S;
   76                 _ns = _ns % 1000000000;
   77         }
   78         /* 9223372037 = ceil(2^63 / 1000000000) */
   79         sb += ((_ns * 9223372037ull) + 0x7fffffff) >> 31;
   80         return (sb);
   81 }
   82 
   83 
   84 typedef struct cv       kcondvar_t;
   85 #define CALLOUT_FLAG_ABSOLUTE C_ABSOLUTE
   86 
   87 typedef enum {
   88         CV_DEFAULT,
   89         CV_DRIVER
   90 } kcv_type_t;
   91 
   92 #define zfs_cv_init(cv, name, type, arg)        do {                    \
   93         const char *_name;                                              \
   94         ASSERT((type) == CV_DEFAULT);                                   \
   95         for (_name = #cv; *_name != '\0'; _name++) {                    \
   96                 if (*_name >= 'a' && *_name <= 'z')                     \
   97                         break;                                          \
   98         }                                                               \
   99         if (*_name == '\0')                                             \
  100                 _name = #cv;                                            \
  101         cv_init((cv), _name);                                           \
  102 } while (0)
  103 #define cv_init(cv, name, type, arg)    zfs_cv_init(cv, name, type, arg)
  104 
  105 
  106 static inline int
  107 cv_wait_sig(kcondvar_t *cvp, kmutex_t *mp)
  108 {
  109 
  110         return (_cv_wait_sig(cvp, &(mp)->lock_object) == 0);
  111 }
  112 
  113 static inline int
  114 cv_timedwait(kcondvar_t *cvp, kmutex_t *mp, clock_t timo)
  115 {
  116         int rc;
  117 
  118         timo -= ddi_get_lbolt();
  119         if (timo <= 0)
  120                 return (-1);
  121         rc = _cv_timedwait_sbt((cvp), &(mp)->lock_object, \
  122             tick_sbt * (timo), 0, C_HARDCLOCK);
  123         if (rc == EWOULDBLOCK)
  124                 return (-1);
  125         return (1);
  126 }
  127 
  128 static inline int
  129 cv_timedwait_sig(kcondvar_t *cvp, kmutex_t *mp, clock_t timo)
  130 {
  131         int rc;
  132 
  133         timo -= ddi_get_lbolt();
  134         if (timo <= 0)
  135                 return (-1);
  136         rc = _cv_timedwait_sig_sbt(cvp, &(mp)->lock_object, \
  137             tick_sbt * (timo), 0, C_HARDCLOCK);
  138         if (rc == EWOULDBLOCK)
  139                 return (-1);
  140         if (rc == EINTR || rc == ERESTART)
  141                 return (0);
  142 
  143         return (1);
  144 }
  145 
  146 #define cv_timedwait_io         cv_timedwait
  147 #define cv_timedwait_idle       cv_timedwait
  148 #define cv_timedwait_sig_io     cv_timedwait_sig
  149 #define cv_wait_io              cv_wait
  150 #define cv_wait_io_sig          cv_wait_sig
  151 #define cv_wait_idle            cv_wait
  152 #define cv_timedwait_io_hires   cv_timedwait_hires
  153 #define cv_timedwait_idle_hires cv_timedwait_hires
  154 
  155 static inline int
  156 cv_timedwait_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim, hrtime_t res,
  157     int flag)
  158 {
  159         hrtime_t hrtime;
  160         int rc;
  161 
  162         ASSERT(tim >= res);
  163 
  164         hrtime = gethrtime();
  165         if (flag == 0)
  166                 tim += hrtime;
  167 
  168         if (hrtime >= tim)
  169                 return (-1);
  170         rc = cv_timedwait_sbt(cvp, mp, zfs_nstosbt(tim),
  171             zfs_nstosbt(res), C_ABSOLUTE);
  172 
  173         if (rc == EWOULDBLOCK)
  174                 return (-1);
  175 
  176         KASSERT(rc == 0, ("unexpected rc value %d", rc));
  177         return (1);
  178 }
  179 
  180 static inline int
  181 cv_timedwait_sig_hires(kcondvar_t *cvp, kmutex_t *mp, hrtime_t tim,
  182     hrtime_t res, int flag)
  183 {
  184         sbintime_t sbt;
  185         hrtime_t hrtime;
  186         int rc;
  187 
  188         ASSERT(tim >= res);
  189 
  190         hrtime = gethrtime();
  191         if (flag == 0)
  192                 tim += hrtime;
  193 
  194         if (hrtime >= tim)
  195                 return (-1);
  196 
  197         sbt = zfs_nstosbt(tim);
  198         rc = cv_timedwait_sig_sbt(cvp, mp, sbt, zfs_nstosbt(res), C_ABSOLUTE);
  199 
  200         switch (rc) {
  201         case EWOULDBLOCK:
  202                 return (-1);
  203         case EINTR:
  204         case ERESTART:
  205                 return (0);
  206         default:
  207                 KASSERT(rc == 0, ("unexpected rc value %d", rc));
  208                 return (1);
  209         }
  210 }
  211 
  212 #endif  /* _OPENSOLARIS_SYS_CONDVAR_H_ */

Cache object: 2bbdf999e47cf7e602188c3ffe5a6cbf


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.