Path: blob/main/sys/contrib/openzfs/lib/libspl/condvar.c
96339 views
// SPDX-License-Identifier: CDDL-1.01/*2* CDDL HEADER START3*4* The contents of this file are subject to the terms of the5* Common Development and Distribution License (the "License").6* You may not use this file except in compliance with the License.7*8* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE9* or https://opensource.org/licenses/CDDL-1.0.10* See the License for the specific language governing permissions11* and limitations under the License.12*13* When distributing Covered Code, include this CDDL HEADER in each14* file and include the License file at usr/src/OPENSOLARIS.LICENSE.15* If applicable, add the following below this CDDL HEADER, with the16* fields enclosed by brackets "[]" replaced with your own identifying17* information: Portions Copyright [yyyy] [name of copyright owner]18*19* CDDL HEADER END20*/21/*22* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.23* Copyright (c) 2012, 2018 by Delphix. All rights reserved.24* Copyright (c) 2016 Actifio, Inc. All rights reserved.25* Copyright (c) 2025, Klara, Inc.26*/2728#include <assert.h>29#include <pthread.h>30#include <errno.h>31#include <string.h>32#include <sys/timer.h>33#include <sys/condvar.h>3435/*36* =========================================================================37* condition variables38* =========================================================================39*/4041void42cv_init(kcondvar_t *cv, char *name, int type, void *arg)43{44(void) name, (void) type, (void) arg;45VERIFY0(pthread_cond_init(cv, NULL));46}4748void49cv_destroy(kcondvar_t *cv)50{51VERIFY0(pthread_cond_destroy(cv));52}5354void55cv_wait(kcondvar_t *cv, kmutex_t *mp)56{57memset(&mp->m_owner, 0, sizeof (pthread_t));58VERIFY0(pthread_cond_wait(cv, &mp->m_lock));59mp->m_owner = pthread_self();60}6162int63cv_wait_sig(kcondvar_t *cv, kmutex_t *mp)64{65cv_wait(cv, mp);66return (1);67}6869int70cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime)71{72int error;73struct timeval tv;74struct timespec ts;75clock_t delta;7677delta = abstime - ddi_get_lbolt();78if (delta <= 0)79return (-1);8081VERIFY0(gettimeofday(&tv, NULL));8283ts.tv_sec = tv.tv_sec + delta / hz;84ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC + (delta % hz) * (NANOSEC / hz);85if (ts.tv_nsec >= NANOSEC) {86ts.tv_sec++;87ts.tv_nsec -= NANOSEC;88}8990memset(&mp->m_owner, 0, sizeof (pthread_t));91error = pthread_cond_timedwait(cv, &mp->m_lock, &ts);92mp->m_owner = pthread_self();9394if (error == ETIMEDOUT)95return (-1);9697VERIFY0(error);9899return (1);100}101102int103cv_timedwait_hires(kcondvar_t *cv, kmutex_t *mp, hrtime_t tim, hrtime_t res,104int flag)105{106(void) res;107int error;108struct timeval tv;109struct timespec ts;110hrtime_t delta;111112ASSERT(flag == 0 || flag == CALLOUT_FLAG_ABSOLUTE);113114delta = tim;115if (flag & CALLOUT_FLAG_ABSOLUTE)116delta -= gethrtime();117118if (delta <= 0)119return (-1);120121VERIFY0(gettimeofday(&tv, NULL));122123ts.tv_sec = tv.tv_sec + delta / NANOSEC;124ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC + (delta % NANOSEC);125if (ts.tv_nsec >= NANOSEC) {126ts.tv_sec++;127ts.tv_nsec -= NANOSEC;128}129130memset(&mp->m_owner, 0, sizeof (pthread_t));131error = pthread_cond_timedwait(cv, &mp->m_lock, &ts);132mp->m_owner = pthread_self();133134if (error == ETIMEDOUT)135return (-1);136137VERIFY0(error);138139return (1);140}141142void143cv_signal(kcondvar_t *cv)144{145VERIFY0(pthread_cond_signal(cv));146}147148void149cv_broadcast(kcondvar_t *cv)150{151VERIFY0(pthread_cond_broadcast(cv));152}153154155