From patchwork Wed Dec 7 06:04:06 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matt Oliver X-Patchwork-Id: 1707 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.65.86 with SMTP id o83csp124297vsa; Tue, 6 Dec 2016 22:04:19 -0800 (PST) X-Received: by 10.194.125.43 with SMTP id mn11mr18573128wjb.14.1481090659038; Tue, 06 Dec 2016 22:04:19 -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 f84si6992421wmi.127.2016.12.06.22.04.18; Tue, 06 Dec 2016 22:04:18 -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 C4C7F689BF4; Wed, 7 Dec 2016 08:04:04 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-io0-f193.google.com (mail-io0-f193.google.com [209.85.223.193]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C991E689A40 for ; Wed, 7 Dec 2016 08:03:57 +0200 (EET) Received: by mail-io0-f193.google.com with SMTP id r94so11359685ioe.1 for ; Tue, 06 Dec 2016 22:04:08 -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=2+vHRyn4r/GD8za2lPVQwIUj5AbGEGjlVso882/DvWo=; b=NAMETFRyFK/DnYOzD+MHpJoFJPB8CkdMBKAjmbg2juu0WMDbnsAPyjr92DJY6GpVRz AtCwO0zk+WmDLPf9dvAUQLMjYne03CCTpobhX0wrZNbHa2o9lES1utt+Mc4vNE/9he2M 2uOTfUTo8t0j3ysXTgawWXyaGql+NSwxdDuzRQBwgkRp4oe+ZgEU7qyS+qt+PzNP9IEz wLFeNPErzC6MbMKru7ZiO276NaWvqUg/EGjOfu9Pg8RXNeBBeCEni8v8O2jVWzZia6By Aik9glu5YhlVnHE+XjOxRWihiHmWRFEZ1TKknbS5I0hlk0T62bYLPdEXPDKc0i0SCz+p Y7/w== 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=2+vHRyn4r/GD8za2lPVQwIUj5AbGEGjlVso882/DvWo=; b=QD9NG6gWo2+aWT8y5J45OJeTq7/W/92TNa073QOD2SKJJIJhiIoFv8hCaSZQCtokqP r0YS9fjls72n4D+G58kPi2XevXENMP8Azjcnu6IA/vb61zoHvEN5UUjCDI3P3wnSTGR8 dpt4L0Rp0DKqZOB8LDntGnvy7OKoGorYq9NhmMhpEmu8yY+9H9ZaNii1C6n+Zid8KgEw qNHQBLoLA4IJLOxK+Zon9nhvIRfAS+oo72CrcsNau9A0F0tMgOF3x+PDomdLvfRvjMHH DmyHUU/lwYTLZKS7bho2MEzAKkgYMNNXxlwSNWnUqZ2G8q+vU31Ll59Tblxj3vxzZceY BOGw== X-Gm-Message-State: AKaTC02HEtUIud0YCT9dM4e2e6WMHESMsl6I30qGdRww/9RBP//BoUINsca+zyqQRZraqmnMlw8XdZyebAuK8Q== X-Received: by 10.107.44.5 with SMTP id s5mr58880885ios.10.1481090647065; Tue, 06 Dec 2016 22:04:07 -0800 (PST) MIME-Version: 1.0 Received: by 10.36.65.90 with HTTP; Tue, 6 Dec 2016 22:04:06 -0800 (PST) From: Matt Oliver Date: Wed, 7 Dec 2016 17:04:06 +1100 Message-ID: To: FFmpeg development discussions and patches X-Content-Filtered-By: Mailman/MimeDel 2.1.20 Subject: [FFmpeg-devel] [PATCH 1/3] 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); +} +