Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/openzfs/lib/libspl/condvar.c
96339 views
1
// SPDX-License-Identifier: CDDL-1.0
2
/*
3
* CDDL HEADER START
4
*
5
* The contents of this file are subject to the terms of the
6
* Common Development and Distribution License (the "License").
7
* You may not use this file except in compliance with the License.
8
*
9
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10
* or https://opensource.org/licenses/CDDL-1.0.
11
* See the License for the specific language governing permissions
12
* and limitations under the License.
13
*
14
* When distributing Covered Code, include this CDDL HEADER in each
15
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16
* If applicable, add the following below this CDDL HEADER, with the
17
* fields enclosed by brackets "[]" replaced with your own identifying
18
* information: Portions Copyright [yyyy] [name of copyright owner]
19
*
20
* CDDL HEADER END
21
*/
22
/*
23
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24
* Copyright (c) 2012, 2018 by Delphix. All rights reserved.
25
* Copyright (c) 2016 Actifio, Inc. All rights reserved.
26
* Copyright (c) 2025, Klara, Inc.
27
*/
28
29
#include <assert.h>
30
#include <pthread.h>
31
#include <errno.h>
32
#include <string.h>
33
#include <sys/timer.h>
34
#include <sys/condvar.h>
35
36
/*
37
* =========================================================================
38
* condition variables
39
* =========================================================================
40
*/
41
42
void
43
cv_init(kcondvar_t *cv, char *name, int type, void *arg)
44
{
45
(void) name, (void) type, (void) arg;
46
VERIFY0(pthread_cond_init(cv, NULL));
47
}
48
49
void
50
cv_destroy(kcondvar_t *cv)
51
{
52
VERIFY0(pthread_cond_destroy(cv));
53
}
54
55
void
56
cv_wait(kcondvar_t *cv, kmutex_t *mp)
57
{
58
memset(&mp->m_owner, 0, sizeof (pthread_t));
59
VERIFY0(pthread_cond_wait(cv, &mp->m_lock));
60
mp->m_owner = pthread_self();
61
}
62
63
int
64
cv_wait_sig(kcondvar_t *cv, kmutex_t *mp)
65
{
66
cv_wait(cv, mp);
67
return (1);
68
}
69
70
int
71
cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime)
72
{
73
int error;
74
struct timeval tv;
75
struct timespec ts;
76
clock_t delta;
77
78
delta = abstime - ddi_get_lbolt();
79
if (delta <= 0)
80
return (-1);
81
82
VERIFY0(gettimeofday(&tv, NULL));
83
84
ts.tv_sec = tv.tv_sec + delta / hz;
85
ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC + (delta % hz) * (NANOSEC / hz);
86
if (ts.tv_nsec >= NANOSEC) {
87
ts.tv_sec++;
88
ts.tv_nsec -= NANOSEC;
89
}
90
91
memset(&mp->m_owner, 0, sizeof (pthread_t));
92
error = pthread_cond_timedwait(cv, &mp->m_lock, &ts);
93
mp->m_owner = pthread_self();
94
95
if (error == ETIMEDOUT)
96
return (-1);
97
98
VERIFY0(error);
99
100
return (1);
101
}
102
103
int
104
cv_timedwait_hires(kcondvar_t *cv, kmutex_t *mp, hrtime_t tim, hrtime_t res,
105
int flag)
106
{
107
(void) res;
108
int error;
109
struct timeval tv;
110
struct timespec ts;
111
hrtime_t delta;
112
113
ASSERT(flag == 0 || flag == CALLOUT_FLAG_ABSOLUTE);
114
115
delta = tim;
116
if (flag & CALLOUT_FLAG_ABSOLUTE)
117
delta -= gethrtime();
118
119
if (delta <= 0)
120
return (-1);
121
122
VERIFY0(gettimeofday(&tv, NULL));
123
124
ts.tv_sec = tv.tv_sec + delta / NANOSEC;
125
ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC + (delta % NANOSEC);
126
if (ts.tv_nsec >= NANOSEC) {
127
ts.tv_sec++;
128
ts.tv_nsec -= NANOSEC;
129
}
130
131
memset(&mp->m_owner, 0, sizeof (pthread_t));
132
error = pthread_cond_timedwait(cv, &mp->m_lock, &ts);
133
mp->m_owner = pthread_self();
134
135
if (error == ETIMEDOUT)
136
return (-1);
137
138
VERIFY0(error);
139
140
return (1);
141
}
142
143
void
144
cv_signal(kcondvar_t *cv)
145
{
146
VERIFY0(pthread_cond_signal(cv));
147
}
148
149
void
150
cv_broadcast(kcondvar_t *cv)
151
{
152
VERIFY0(pthread_cond_broadcast(cv));
153
}
154
155