4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync/* $Id$ */
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync/** @file
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync * IPRT - RTSemEventMultiWait, implementation based on RTSemEventMultiWaitEx.
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync */
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync/*
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync * Copyright (C) 2010-2012 Oracle Corporation
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync *
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync * available from http://www.virtualbox.org. This file is free software;
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync * you can redistribute it and/or modify it under the terms of the GNU
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync * General Public License (GPL) as published by the Free Software
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync *
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync * The contents of this file may alternatively be used under the terms
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync * of the Common Development and Distribution License Version 1.0
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync * VirtualBox OSE distribution, in which case the provisions of the
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync * CDDL are applicable instead of those of the GPL.
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync *
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync * You may elect to license modified versions of this file under the
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync * terms and conditions of either the GPL or the CDDL or both.
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync */
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync/*******************************************************************************
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync* Header Files *
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync*******************************************************************************/
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync#include "internal/iprt.h"
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync#include <iprt/semaphore.h>
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync#include <iprt/time.h>
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync/*******************************************************************************
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync* Defined Constants And Macros *
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync*******************************************************************************/
64eea8161bef2aa3c6516481383c830bca27abfevboxsync/** Too lazy to include the right OS/2 header, duplicating the define we
64eea8161bef2aa3c6516481383c830bca27abfevboxsync * need here. */
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync#define MY_SEM_INDEFINITE_WAIT UINT32_MAX
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync/**
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync * Converts the timeout to a millisecond value that can be fed to KernBlock.
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync *
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync * @returns Relative timeout in milliseconds.
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync * @param fFlags The semaphore wait flags.
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync * @param uTimeout The timeout value.
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync */
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsyncuint32_t rtR0SemWaitOs2ConvertTimeout(uint32_t fFlags, uint64_t uTimeout)
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync{
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync /*
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync * Simple & common cases.
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync */
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync if (fFlags & RTSEMWAIT_FLAGS_INDEFINITE)
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync return MY_SEM_INDEFINITE_WAIT;
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync
64eea8161bef2aa3c6516481383c830bca27abfevboxsync if ( (fFlags & (RTSEMWAIT_FLAGS_MILLISECS | RTSEMWAIT_FLAGS_ABSOLUTE))
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync == RTSEMWAIT_FLAGS_MILLISECS)
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync {
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync if (uTimeout < UINT32_MAX)
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync return (uint32_t)uTimeout;
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync return MY_SEM_INDEFINITE_WAIT;
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync }
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync if (!uTimeout)
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync return 0;
64eea8161bef2aa3c6516481383c830bca27abfevboxsync
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync if (uTimeout == UINT64_MAX)
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync return MY_SEM_INDEFINITE_WAIT;
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync /*
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync * For the more complicated cases (nano or/and abs), convert thru nano (lazy bird).
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync */
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync if (fFlags & RTSEMWAIT_FLAGS_MILLISECS)
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync {
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync if (uTimeout >= UINT64_MAX / RT_NS_1MS * RT_NS_1MS)
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync return MY_SEM_INDEFINITE_WAIT;
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync uTimeout = uTimeout * RT_NS_1MS;
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync }
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync if (fFlags & RTSEMWAIT_FLAGS_ABSOLUTE)
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync {
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync uint64_t u64Now = RTTimeSystemNanoTS();
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync if (u64Now >= uTimeout)
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync return 0;
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync uTimeout = uTimeout - u64Now;
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync }
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync uTimeout /= RT_NS_1MS;
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync if (uTimeout >= UINT32_MAX)
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync return MY_SEM_INDEFINITE_WAIT;
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync return (uint32_t)uTimeout;
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync}
4eb60291a3736df8e5c706848a0c5dfa75a5814fvboxsync