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
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.
13 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
14 * Copyright 2017 RackTop Systems.
21 /* This is the API we're emulating */
22 #include <sys/condvar.h>
24 #include <sys/errno.h>
25 #include <sys/debug.h>
26 #include <sys/thread.h>
27 #include <sys/systm.h>
29 /* avoiding synch.h */
30 int _lwp_cond_wait(lwp_cond_t
*, lwp_mutex_t
*);
31 int _lwp_cond_timedwait(lwp_cond_t
*, lwp_mutex_t
*, timespec_t
*);
32 int _lwp_cond_reltimedwait(lwp_cond_t
*, lwp_mutex_t
*, timespec_t
*);
33 int _lwp_cond_signal(lwp_cond_t
*);
34 int _lwp_cond_broadcast(lwp_cond_t
*);
37 extern clock_t ddi_get_lbolt(void);
39 static int cv__wait(kcondvar_t
*, kmutex_t
*, int);
40 static clock_t cv__twait(kcondvar_t
*, kmutex_t
*, clock_t, int, int);
42 static const lwp_cond_t default_cv
=
43 {{{0, 0, 0, 0}, USYNC_THREAD
, _COND_MAGIC
}, 0};
48 cv_init(kcondvar_t
*cv
, char *name
, kcv_type_t typ
, void *arg
)
55 cv_destroy(kcondvar_t
*cv
)
60 cv_signal(kcondvar_t
*cv
)
62 (void) _lwp_cond_signal(cv
);
66 cv_broadcast(kcondvar_t
*cv
)
68 (void) _lwp_cond_broadcast(cv
);
72 cv_wait(kcondvar_t
*cv
, kmutex_t
*mp
)
74 (void) cv__wait(cv
, mp
, 0);
78 cv_wait_sig(kcondvar_t
*cv
, kmutex_t
*mp
)
80 return (cv__wait(cv
, mp
, 1));
84 cv__wait(kcondvar_t
*cv
, kmutex_t
*mp
, int sigok
)
89 ASSERT(mp
->m_owner
== _curthread());
90 mp
->m_owner
= _KTHREAD_INVALID
;
91 err
= _lwp_cond_wait(cv
, &mp
->m_lock
);
92 mp
->m_owner
= _curthread();
105 cv_timedwait(kcondvar_t
*cv
, kmutex_t
*mp
, clock_t abstime
)
109 delta
= abstime
- ddi_get_lbolt();
110 return (cv__twait(cv
, mp
, delta
, 0, 0));
114 cv_timedwait_sig(kcondvar_t
*cv
, kmutex_t
*mp
, clock_t abstime
)
118 delta
= abstime
- ddi_get_lbolt();
119 return (cv__twait(cv
, mp
, delta
, 1, 0));
124 cv_timedwait_hires(kcondvar_t
*cv
, kmutex_t
*mp
, hrtime_t tim
, hrtime_t res
,
130 if (flag
& CALLOUT_FLAG_ABSOLUTE
)
131 delta
-= gethrtime();
132 return (cv__twait(cv
, mp
, delta
, 0, 1));
136 cv_reltimedwait(kcondvar_t
*cv
, kmutex_t
*mp
, clock_t delta
, time_res_t res
)
138 _NOTE(ARGUNUSED(res
))
140 return (cv__twait(cv
, mp
, delta
, 0, 0));
144 cv_reltimedwait_sig(kcondvar_t
*cv
, kmutex_t
*mp
, clock_t delta
,
147 _NOTE(ARGUNUSED(res
))
149 return (cv__twait(cv
, mp
, delta
, 1, 0));
153 * Factored out implementation of all the cv_*timedwait* functions.
154 * Note that the delta passed in is relative to the (simulated)
155 * current time reported by ddi_get_lbolt(). Convert that to
156 * timespec format and keep calling _lwp_cond_reltimedwait,
157 * which (NB!) decrements that delta in-place!
160 cv__twait(kcondvar_t
*cv
, kmutex_t
*mp
, clock_t delta
, int sigok
, int hires
)
169 ts
.tv_sec
= delta
/ NANOSEC
;
170 ts
.tv_nsec
= delta
% NANOSEC
;
172 ts
.tv_sec
= delta
/ hz
;
173 ts
.tv_nsec
= (delta
% hz
) * (NANOSEC
/ hz
);
177 if (ts
.tv_sec
== 0 && ts
.tv_nsec
== 0)
180 ASSERT(mp
->m_owner
== _curthread());
181 mp
->m_owner
= _KTHREAD_INVALID
;
182 err
= _lwp_cond_reltimedwait(cv
, &mp
->m_lock
, &ts
);
183 mp
->m_owner
= _curthread();