/src/x265/source/common/wavefront.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /***************************************************************************** |
2 | | * Copyright (C) 2013-2020 MulticoreWare, Inc |
3 | | * |
4 | | * Authors: Steve Borho <steve@borho.org> |
5 | | * Min Chen <chenm003@163.com> |
6 | | * |
7 | | * This program is free software; you can redistribute it and/or modify |
8 | | * it under the terms of the GNU General Public License as published by |
9 | | * the Free Software Foundation; either version 2 of the License, or |
10 | | * (at your option) any later version. |
11 | | * |
12 | | * This program is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | * GNU General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU General Public License |
18 | | * along with this program; if not, write to the Free Software |
19 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. |
20 | | * |
21 | | * This program is also available under a commercial proprietary license. |
22 | | * For more information, contact us at license @ x265.com |
23 | | *****************************************************************************/ |
24 | | |
25 | | #include "threadpool.h" |
26 | | #include "threading.h" |
27 | | #include "wavefront.h" |
28 | | #include "common.h" |
29 | | |
30 | | namespace X265_NS { |
31 | | // x265 private namespace |
32 | | |
33 | | bool WaveFront::init(int numRows) |
34 | 0 | { |
35 | 0 | m_numRows = numRows; |
36 | |
|
37 | 0 | m_numWords = (numRows + 31) >> 5; |
38 | 0 | m_internalDependencyBitmap = X265_MALLOC(uint32_t, m_numWords); |
39 | 0 | if (m_internalDependencyBitmap) |
40 | 0 | memset((void*)m_internalDependencyBitmap, 0, sizeof(uint32_t) * m_numWords); |
41 | |
|
42 | 0 | m_externalDependencyBitmap = X265_MALLOC(uint32_t, m_numWords); |
43 | 0 | if (m_externalDependencyBitmap) |
44 | 0 | memset((void*)m_externalDependencyBitmap, 0, sizeof(uint32_t) * m_numWords); |
45 | |
|
46 | 0 | m_row_to_idx = X265_MALLOC(uint32_t, m_numRows); |
47 | 0 | m_idx_to_row = X265_MALLOC(uint32_t, m_numRows); |
48 | |
|
49 | 0 | return m_internalDependencyBitmap && m_externalDependencyBitmap; |
50 | 0 | } |
51 | | |
52 | | WaveFront::~WaveFront() |
53 | 0 | { |
54 | 0 | x265_free((void*)m_row_to_idx); |
55 | 0 | x265_free((void*)m_idx_to_row); |
56 | |
|
57 | 0 | x265_free((void*)m_internalDependencyBitmap); |
58 | 0 | x265_free((void*)m_externalDependencyBitmap); |
59 | 0 | } |
60 | | |
61 | | void WaveFront::clearEnabledRowMask() |
62 | 0 | { |
63 | 0 | memset((void*)m_externalDependencyBitmap, 0, sizeof(uint32_t) * m_numWords); |
64 | 0 | memset((void*)m_internalDependencyBitmap, 0, sizeof(uint32_t) * m_numWords); |
65 | 0 | } |
66 | | |
67 | | void WaveFront::enqueueRow(int row) |
68 | 0 | { |
69 | 0 | uint32_t bit = 1 << (row & 31); |
70 | 0 | ATOMIC_OR(&m_internalDependencyBitmap[row >> 5], bit); |
71 | 0 | } |
72 | | |
73 | | void WaveFront::enableRow(int row) |
74 | 0 | { |
75 | 0 | uint32_t bit = 1 << (row & 31); |
76 | 0 | ATOMIC_OR(&m_externalDependencyBitmap[row >> 5], bit); |
77 | 0 | } |
78 | | |
79 | | void WaveFront::enableAllRows() |
80 | 0 | { |
81 | 0 | memset((void*)m_externalDependencyBitmap, ~0, sizeof(uint32_t) * m_numWords); |
82 | 0 | } |
83 | | |
84 | | bool WaveFront::dequeueRow(int row) |
85 | 0 | { |
86 | 0 | uint32_t bit = 1 << (row & 31); |
87 | 0 | return !!(ATOMIC_AND(&m_internalDependencyBitmap[row >> 5], ~bit) & bit); |
88 | 0 | } |
89 | | |
90 | | void WaveFront::findJob(int threadId) |
91 | 0 | { |
92 | 0 | unsigned long id; |
93 | | |
94 | | /* Loop over each word until all available rows are finished */ |
95 | 0 | for (int w = 0; w < m_numWords; w++) |
96 | 0 | { |
97 | 0 | uint32_t oldval = m_internalDependencyBitmap[w] & m_externalDependencyBitmap[w]; |
98 | 0 | while (oldval) |
99 | 0 | { |
100 | 0 | CTZ(id, oldval); |
101 | |
|
102 | 0 | uint32_t bit = 1 << id; |
103 | 0 | if (ATOMIC_AND(&m_internalDependencyBitmap[w], ~bit) & bit) |
104 | 0 | { |
105 | | /* we cleared the bit, we get to process the row */ |
106 | 0 | processRow(w * 32 + id, threadId); |
107 | 0 | m_helpWanted = true; |
108 | 0 | return; /* check for a higher priority task */ |
109 | 0 | } |
110 | | |
111 | 0 | oldval = m_internalDependencyBitmap[w] & m_externalDependencyBitmap[w]; |
112 | 0 | } |
113 | 0 | } |
114 | | |
115 | 0 | m_helpWanted = false; |
116 | 0 | } |
117 | | } |