1 /*
2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #ifndef VPX_VP8_COMMON_THREADING_H_
12 #define VPX_VP8_COMMON_THREADING_H_
13
14 #include "./vpx_config.h"
15
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19
20 #if CONFIG_OS_SUPPORT && CONFIG_MULTITHREAD
21
22 #if defined(_WIN32) && !HAVE_PTHREAD_H
23 /* Win32 */
24 #include <windows.h>
25 #else
26 /* pthreads */
27 #ifdef __APPLE__
28 #include <mach/mach_init.h>
29 #include <mach/semaphore.h>
30 #include <mach/task.h>
31 #include <time.h>
32 #include <unistd.h>
33 #else
34 #include <semaphore.h>
35 #endif
36 #endif
37
38 /* Synchronization macros: Win32 and Pthreads */
39 #if defined(_WIN32) && !HAVE_PTHREAD_H
40 #define vp8_sem_t HANDLE
41 #define vp8_sem_init(sem, pshared, value) \
42 (int)((*sem = CreateSemaphore(NULL, value, 32768, NULL)) == NULL)
43 #define vp8_sem_wait(sem) \
44 (int)(WAIT_OBJECT_0 != WaitForSingleObject(*sem, INFINITE))
45 #define vp8_sem_post(sem) ReleaseSemaphore(*sem, 1, NULL)
46 #define vp8_sem_destroy(sem) \
47 if (*sem) ((int)(CloseHandle(*sem)) == TRUE)
48 #define thread_sleep(nms) Sleep(nms)
49
50 #else
51
52 #ifdef __APPLE__
53 #define vp8_sem_t semaphore_t
54 #define vp8_sem_init(sem, pshared, value) \
55 semaphore_create(mach_task_self(), sem, SYNC_POLICY_FIFO, value)
56 #define vp8_sem_wait(sem) semaphore_wait(*sem)
57 #define vp8_sem_post(sem) semaphore_signal(*sem)
58 #define vp8_sem_destroy(sem) semaphore_destroy(mach_task_self(), *sem)
59 #else
60 #include <errno.h>
61 #include <unistd.h>
62 #include <sched.h>
63 #define vp8_sem_t sem_t
64 #define vp8_sem_init sem_init
65 static INLINE int vp8_sem_wait(vp8_sem_t *sem) {
66 int ret;
67 while ((ret = sem_wait(sem)) == -1 && errno == EINTR) {
68 }
69 return ret;
70 }
71 #define vp8_sem_post sem_post
72 #define vp8_sem_destroy sem_destroy
73 #endif /* __APPLE__ */
74 /* Not Windows. Assume pthreads */
75
76 /* thread_sleep implementation: yield unless Linux/Unix. */
77 #if defined(__unix__) || defined(__APPLE__)
78 #define thread_sleep(nms)
79 /* {struct timespec ts;ts.tv_sec=0;
80 ts.tv_nsec = 1000*nms;nanosleep(&ts, NULL);} */
81 #else
82 #define thread_sleep(nms) sched_yield();
83 #endif /* __unix__ || __APPLE__ */
84
85 #endif
86
87 #if VPX_ARCH_X86 || VPX_ARCH_X86_64
88 #include "vpx_ports/x86.h"
89 #else
90 #define x86_pause_hint()
91 #endif
92
93 #include "vpx_util/vpx_atomics.h"
94
vp8_atomic_spin_wait(int mb_col,const vpx_atomic_int * last_row_current_mb_col,const int nsync)95 static INLINE void vp8_atomic_spin_wait(
96 int mb_col, const vpx_atomic_int *last_row_current_mb_col,
97 const int nsync) {
98 while (mb_col > (vpx_atomic_load_acquire(last_row_current_mb_col) - nsync)) {
99 x86_pause_hint();
100 thread_sleep(0);
101 }
102 }
103
104 #endif /* CONFIG_OS_SUPPORT && CONFIG_MULTITHREAD */
105
106 #ifdef __cplusplus
107 } // extern "C"
108 #endif
109
110 #endif // VPX_VP8_COMMON_THREADING_H_
111