From patchwork Fri Dec 2 08:21:13 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Oliver X-Patchwork-Id: 1657 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.65.86 with SMTP id o83csp166396vsa; Fri, 2 Dec 2016 00:35:04 -0800 (PST) X-Received: by 10.28.107.21 with SMTP id g21mr1768565wmc.131.1480667704220; Fri, 02 Dec 2016 00:35:04 -0800 (PST) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id k15si2056765wmi.37.2016.12.02.00.35.03; Fri, 02 Dec 2016 00:35:04 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 0BACA689EAB; Fri, 2 Dec 2016 10:34:53 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-io0-f195.google.com (mail-io0-f195.google.com [209.85.223.195]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 26189689B7D for ; Fri, 2 Dec 2016 10:34:46 +0200 (EET) Received: by mail-io0-f195.google.com with SMTP id s82so6237929ioi.3 for ; Fri, 02 Dec 2016 00:34:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:from:date:message-id:subject:to; bh=SDnnaGUtKy2c/wGkhO/LOe54AWh65X+WPrtSCEeQ4D8=; b=F5Qrf7uSDvBRG4ruEc0lII3bSpgIPJ18FdTgp5mEHvzgUPg09cBcigs35oL3oawesa Kv/CSzb5rGMXId8UL1DNntUpG9eIvRvsQcADWzo73/pT6mLrIR4obMJtu8XhZgNzrK3u wgGC7I24FbepUhFept4XPrRsS28XaVJhJ+s6Odg9OGcjABW7PiygcTp1WwxrxyfR2/93 iVzHXFTotGJt9nOpYDyCnfuR2y29G2HuXS0pSLAFzQBmOBKZNXNAJZ2Z6yMO03sabVVN gHDozDSr9HfGGJrXU1hK1eAxB5dPTczgXCL15E3aEAWMvQCAdjpL8FIRf+7/CCfFmKH7 4djw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=SDnnaGUtKy2c/wGkhO/LOe54AWh65X+WPrtSCEeQ4D8=; b=itWjyr0oVSDGywk7hwPPb1UOg5hGeCOA1+9JFb5+StZDhAKQWKKMnChP9ga8N0myQD mJrmpIgBpTcErJUwueYmRYPGVr2+GWDGdfHVrPoD3mF3Vo/FZohB71k2PzlufWTtTiPt yCcLVOsuAzcfpZ54rorULwor8wcjIKmkjg2DSNSzCsF932moCCowp1PxMosB/LM1BV8v jG+ajlgkeuSj/WJRCRTicFDL8A+xGQG4Fu8R62lEOVD4i5Tqge6eF5aKGjgL2THU7PHf 9b4/rEGH89V38mTVpherD5uhnccYLsSZhxu9zMUu/tMJb19M/Lj+sytp7QBasBcf3CD3 QAtg== X-Gm-Message-State: AKaTC00ojtEZsUNWlEHH6ExOEdeDvEIWX7qo4+NbeJHO7+JjQCdRvCGO3iJ+WGeBKd5mKm9CPuvNhtZYguIZ2g== X-Received: by 10.107.175.147 with SMTP id p19mr37474017ioo.80.1480666874351; Fri, 02 Dec 2016 00:21:14 -0800 (PST) MIME-Version: 1.0 Received: by 10.36.70.138 with HTTP; Fri, 2 Dec 2016 00:21:13 -0800 (PST) From: Matt Oliver Date: Fri, 2 Dec 2016 19:21:13 +1100 Message-ID: To: FFmpeg development discussions and patches X-Content-Filtered-By: Mailman/MimeDel 2.1.20 Subject: [FFmpeg-devel] [PATCH 1/2] avutil/thread: Add pthread_cond_timedwait function. X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: Matt Oliver --- compat/os2threads.h | 24 ++++++++++++++++++++++++ compat/w32pthreads.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ libavutil/thread.h | 6 ++++++ 3 files changed, 80 insertions(+) static inline int strict_pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) { ASSERT_PTHREAD(pthread_once, once_control, init_routine); diff --git a/compat/os2threads.h b/compat/os2threads.h index 40a119f..a8b7824 100644 --- a/compat/os2threads.h +++ b/compat/os2threads.h @@ -31,11 +31,13 @@ #undef __STRICT_ANSI__ /* for _beginthread() */ #include +#include #include #include #include "libavutil/attributes.h" +#include "libavutil/time.h" typedef struct { TID tid; @@ -161,6 +163,28 @@ static av_always_inline int pthread_cond_broadcast(pthread_cond_t *cond) return 0; } +static av_always_inline int pthread_cond_timedwait(pthread_cond_t *cond, + pthread_mutex_t *mutex, + const struct timespec *abstime) +{ + int64_t abs_milli = abstime->tv_nsec * 1000LL + abstime->tv_nsec / 1.0e6; + ULONG t = FFMAX(abs_milli - av_gettime(), 0LL); + + __atomic_increment(&cond->wait_count); + + pthread_mutex_unlock(mutex); + + APIRET ret = DosWaitEventSem(cond->event_sem, t); + + __atomic_decrement(&cond->wait_count); + + DosPostEventSem(cond->ack_sem); + + pthread_mutex_lock(mutex); + + return (ret == ERROR_TIMEOUT) ? ETIMEDOUT : 0; +} + static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) { diff --git a/compat/w32pthreads.h b/compat/w32pthreads.h index 4ac2a99..abd54b2 100644 --- a/compat/w32pthreads.h +++ b/compat/w32pthreads.h @@ -38,6 +38,7 @@ #define WIN32_LEAN_AND_MEAN #include #include +#include #if _WIN32_WINNT < 0x0600 && defined(__MINGW32__) #undef MemoryBarrier @@ -48,6 +49,7 @@ #include "libavutil/common.h" #include "libavutil/internal.h" #include "libavutil/mem.h" +#include "libavutil/time.h" typedef struct pthread_t { void *handle; @@ -171,6 +173,17 @@ static inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex return 0; } +static inline int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, + const struct timespec *abstime) +{ + int64_t abs_milli = abstime->tv_nsec * 1000LL + abstime->tv_nsec / 1.0e6; + DWORD t = FFMAX(abs_milli - av_gettime(), 0LL); + + if (SleepConditionVariableCS(cond, mutex, t) == WAIT_TIMEOUT) + return ETIMEDOUT; + return 0; +} + static inline int pthread_cond_signal(pthread_cond_t *cond) { WakeConditionVariable(cond); @@ -367,6 +380,43 @@ static av_unused int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mu return pthread_mutex_lock(mutex); } +static inline int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, + const struct timespec *abstime) +{ + win32_cond_t *win32_cond = cond->Ptr; + int last_waiter; + int64_t abs_milli = abstime->tv_nsec * 1000LL + abstime->tv_nsec / 1.0e6; + DWORD t = FFMAX(abs_milli - av_gettime(), 0LL); + if (cond_wait) { + cond_wait(cond, mutex, t); + return 0; + } + + /* non native condition variables */ + pthread_mutex_lock(&win32_cond->mtx_broadcast); + pthread_mutex_lock(&win32_cond->mtx_waiter_count); + win32_cond->waiter_count++; + pthread_mutex_unlock(&win32_cond->mtx_waiter_count); + pthread_mutex_unlock(&win32_cond->mtx_broadcast); + + // unlock the external mutex + pthread_mutex_unlock(mutex); + DWORD ret = WaitForSingleObject(win32_cond->semaphore, t); + + pthread_mutex_lock(&win32_cond->mtx_waiter_count); + win32_cond->waiter_count--; + last_waiter = !win32_cond->waiter_count || !win32_cond->is_broadcast; + pthread_mutex_unlock(&win32_cond->mtx_waiter_count); + + if (last_waiter) + SetEvent(win32_cond->waiters_done); + + // lock the external mutex + pthread_mutex_lock(mutex); + + return (ret == WAIT_TIMEOUT) ? ETIMEDOUT : 0; +} + static av_unused int pthread_cond_signal(pthread_cond_t *cond) { win32_cond_t *win32_cond = cond->Ptr; diff --git a/libavutil/thread.h b/libavutil/thread.h index 32ddf40..9d611f2 100644 --- a/libavutil/thread.h +++ b/libavutil/thread.h @@ -108,6 +108,12 @@ static inline int strict_pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t ASSERT_PTHREAD(pthread_cond_wait, cond, mutex); } +static inline int strict_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, + const struct timespec *abstime) +{ + ASSERT_PTHREAD(pthread_cond_timedwait, cond, mutex, abstime); +} +