FFmpeg
w32pthreads.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2010-2011 x264 project
3  *
4  * Authors: Steven Walters <kemuri9@gmail.com>
5  * Pegasys Inc. <http://www.pegasys-inc.com>
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 /**
25  * @file
26  * w32threads to pthreads wrapper
27  */
28 
29 #ifndef COMPAT_W32PTHREADS_H
30 #define COMPAT_W32PTHREADS_H
31 
32 /* Build up a pthread-like API using underlying Windows API. Have only static
33  * methods so as to not conflict with a potentially linked in pthread-win32
34  * library.
35  * As most functions here are used without checking return values,
36  * only implement return values as necessary. */
37 
38 #include <windows.h>
39 #include <process.h>
40 #include <time.h>
41 
42 #include "libavutil/attributes.h"
43 #include "libavutil/common.h"
44 #include "libavutil/internal.h"
45 #include "libavutil/mem.h"
46 #include "libavutil/time.h"
48 
49 typedef struct pthread_t {
50  void *handle;
51  void *(*func)(void* arg);
52  void *arg;
53  void *ret;
54 } *pthread_t;
55 
56 /* use light weight mutex/condition variable API for Windows Vista and later */
57 typedef SRWLOCK pthread_mutex_t;
58 typedef CONDITION_VARIABLE pthread_cond_t;
59 
60 #define PTHREAD_MUTEX_INITIALIZER SRWLOCK_INIT
61 #define PTHREAD_COND_INITIALIZER CONDITION_VARIABLE_INIT
62 
63 #define InitializeCriticalSection(x) InitializeCriticalSectionEx(x, 0, 0)
64 #define WaitForSingleObject(a, b) WaitForSingleObjectEx(a, b, FALSE)
65 
66 #define PTHREAD_CANCEL_ENABLE 1
67 #define PTHREAD_CANCEL_DISABLE 0
68 
69 #if HAVE_WINRT
70 #define THREADFUNC_RETTYPE DWORD
71 #else
72 #define THREADFUNC_RETTYPE unsigned
73 #endif
74 
77 {
79  h->ret = h->func(h->arg);
80  return 0;
81 }
82 
83 static av_unused int pthread_create(pthread_t *thread, const void *unused_attr,
84  void *(*start_routine)(void*), void *arg)
85 {
86  pthread_t ret;
87 
88  ret = av_mallocz(sizeof(*ret));
89  if (!ret)
90  return EAGAIN;
91 
92  ret->func = start_routine;
93  ret->arg = arg;
94 #if HAVE_WINRT
95  ret->handle = (void*)CreateThread(NULL, 0, win32thread_worker, ret,
96  0, NULL);
97 #else
98  ret->handle = (void*)_beginthreadex(NULL, 0, win32thread_worker, ret,
99  0, NULL);
100 #endif
101 
102  if (!ret->handle) {
103  av_free(ret);
104  return EAGAIN;
105  }
106 
107  *thread = ret;
108 
109  return 0;
110 }
111 
112 static av_unused int pthread_join(pthread_t thread, void **value_ptr)
113 {
114  DWORD ret = WaitForSingleObject(thread->handle, INFINITE);
115  if (ret != WAIT_OBJECT_0) {
116  if (ret == WAIT_ABANDONED)
117  return EINVAL;
118  else
119  return EDEADLK;
120  }
121  if (value_ptr)
122  *value_ptr = thread->ret;
123  CloseHandle(thread->handle);
124  av_free(thread);
125  return 0;
126 }
127 
128 static inline int pthread_mutex_init(pthread_mutex_t *m, void* attr)
129 {
130  InitializeSRWLock(m);
131  return 0;
132 }
134 {
135  /* Unlocked SWR locks use no resources */
136  return 0;
137 }
138 static inline int pthread_mutex_lock(pthread_mutex_t *m)
139 {
140  AcquireSRWLockExclusive(m);
141  return 0;
142 }
144 {
145  ReleaseSRWLockExclusive(m);
146  return 0;
147 }
148 
149 typedef INIT_ONCE pthread_once_t;
150 #define PTHREAD_ONCE_INIT INIT_ONCE_STATIC_INIT
151 
152 static av_unused int pthread_once(pthread_once_t *once_control, void (*init_routine)(void))
153 {
154  BOOL pending = FALSE;
155  InitOnceBeginInitialize(once_control, 0, &pending, NULL);
156  if (pending)
157  init_routine();
158  InitOnceComplete(once_control, 0, NULL);
159  return 0;
160 }
161 
162 static inline int pthread_cond_init(pthread_cond_t *cond, const void *unused_attr)
163 {
164  InitializeConditionVariable(cond);
165  return 0;
166 }
167 
168 /* native condition variables do not destroy */
170 {
171  return 0;
172 }
173 
175 {
176  WakeAllConditionVariable(cond);
177  return 0;
178 }
179 
181 {
182  SleepConditionVariableSRW(cond, mutex, INFINITE, 0);
183  return 0;
184 }
185 
187  const struct timespec *abstime)
188 {
189  int64_t abs_milli = abstime->tv_sec * 1000LL + abstime->tv_nsec / 1000000;
190  DWORD t = av_clip64(abs_milli - av_gettime() / 1000, 0, UINT32_MAX);
191 
192  if (!SleepConditionVariableSRW(cond, mutex, t, 0)) {
193  DWORD err = GetLastError();
194  if (err == ERROR_TIMEOUT)
195  return ETIMEDOUT;
196  else
197  return EINVAL;
198  }
199  return 0;
200 }
201 
203 {
204  WakeConditionVariable(cond);
205  return 0;
206 }
207 
208 static inline int pthread_setcancelstate(int state, int *oldstate)
209 {
210  return 0;
211 }
212 
213 static inline int win32_thread_setname(const char *name)
214 {
215 #if !HAVE_UWP
216  typedef HRESULT (WINAPI *SetThreadDescriptionFn)(HANDLE, PCWSTR);
217 
218  // Although SetThreadDescription lives in kernel32.dll, on Windows Server 2016,
219  // Windows 10 LTSB 2016 and Windows 10 version 1607, it was only available in
220  // kernelbase.dll. So, load it from there for maximum coverage.
221  HMODULE kernelbase = GetModuleHandleW(L"kernelbase.dll");
222  if (!kernelbase)
223  return AVERROR(ENOSYS);
224 
225  SetThreadDescriptionFn pSetThreadDescription =
226  (SetThreadDescriptionFn)GetProcAddress(kernelbase, "SetThreadDescription");
227  if (!pSetThreadDescription)
228  return AVERROR(ENOSYS);
229 
230  wchar_t *wname;
231  if (utf8towchar(name, &wname) < 0)
232  return AVERROR(ENOMEM);
233 
234  HRESULT hr = pSetThreadDescription(GetCurrentThread(), wname);
235  av_free(wname);
236  return SUCCEEDED(hr) ? 0 : AVERROR(EINVAL);
237 #else
238  // UWP is not supported because we cannot use LoadLibrary/GetProcAddress to
239  // detect the availability of the SetThreadDescription API. There is a small
240  // gap in Windows builds 1507-1607 where it was not available. UWP allows
241  // querying the availability of APIs with QueryOptionalDelayLoadedAPI, but it
242  // requires /DELAYLOAD:kernel32.dll during linking, and we cannot enforce that.
243  return AVERROR(ENOSYS);
244 #endif
245 }
246 
247 #endif /* COMPAT_W32PTHREADS_H */
pthread_mutex_t
_fmutex pthread_mutex_t
Definition: os2threads.h:53
wchar_filename.h
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
pthread_mutex_lock
static int pthread_mutex_lock(pthread_mutex_t *m)
Definition: w32pthreads.h:138
int64_t
long long int64_t
Definition: coverity.c:34
av_unused
#define av_unused
Definition: attributes.h:131
win32thread_worker
static av_unused THREADFUNC_RETTYPE __stdcall attribute_align_arg win32thread_worker(void *arg)
Definition: w32pthreads.h:76
pthread_cond_timedwait
static int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)
Definition: w32pthreads.h:186
pthread_cond_init
static int pthread_cond_init(pthread_cond_t *cond, const void *unused_attr)
Definition: w32pthreads.h:162
pthread_cond_broadcast
static int pthread_cond_broadcast(pthread_cond_t *cond)
Definition: w32pthreads.h:174
pthread_cond_wait
static int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
Definition: w32pthreads.h:180
av_clip64
#define av_clip64
Definition: common.h:103
mutex
static AVMutex mutex
Definition: resman.c:61
pthread_cond_destroy
static int pthread_cond_destroy(pthread_cond_t *cond)
Definition: w32pthreads.h:169
pthread_t::arg
void * arg
Definition: os2threads.h:47
pthread_once
static av_unused int pthread_once(pthread_once_t *once_control, void(*init_routine)(void))
Definition: w32pthreads.h:152
THREADFUNC_RETTYPE
#define THREADFUNC_RETTYPE
Definition: w32pthreads.h:72
pthread_mutex_t
SRWLOCK pthread_mutex_t
Definition: w32pthreads.h:57
pthread_mutex_destroy
static int pthread_mutex_destroy(pthread_mutex_t *m)
Definition: w32pthreads.h:133
arg
const char * arg
Definition: jacosubdec.c:67
NULL
#define NULL
Definition: coverity.c:32
pthread_t::ret
void * ret
Definition: w32pthreads.h:53
time.h
pthread_cond_t
CONDITION_VARIABLE pthread_cond_t
Definition: w32pthreads.h:58
attribute_align_arg
#define attribute_align_arg
Definition: internal.h:50
pthread_create
static av_unused int pthread_create(pthread_t *thread, const void *unused_attr, void *(*start_routine)(void *), void *arg)
Definition: w32pthreads.h:83
attributes.h
pthread_t
Definition: os2threads.h:44
pthread_cond_signal
static int pthread_cond_signal(pthread_cond_t *cond)
Definition: w32pthreads.h:202
pthread_t::handle
void * handle
Definition: w32pthreads.h:50
internal.h
common.h
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
pthread_cond_t
Definition: os2threads.h:58
pthread_join
static av_unused int pthread_join(pthread_t thread, void **value_ptr)
Definition: w32pthreads.h:112
pthread_setcancelstate
static int pthread_setcancelstate(int state, int *oldstate)
Definition: w32pthreads.h:208
ret
ret
Definition: filter_design.txt:187
pthread_mutex_init
static int pthread_mutex_init(pthread_mutex_t *m, void *attr)
Definition: w32pthreads.h:128
state
static struct @521 state
pthread_once_t
INIT_ONCE pthread_once_t
Definition: w32pthreads.h:149
L
#define L(x)
Definition: vpx_arith.h:36
pthread_once_t
Definition: os2threads.h:66
av_gettime
int64_t av_gettime(void)
Get the current time in microseconds.
Definition: time.c:39
mem.h
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
WaitForSingleObject
#define WaitForSingleObject(a, b)
Definition: w32pthreads.h:64
win32_thread_setname
static int win32_thread_setname(const char *name)
Definition: w32pthreads.h:213
h
h
Definition: vp9dsp_template.c:2070
pthread_mutex_unlock
static int pthread_mutex_unlock(pthread_mutex_t *m)
Definition: w32pthreads.h:143
cond
int(* cond)(enum AVPixelFormat pix_fmt)
Definition: pixdesc_query.c:28