annotate foosdk/sdk/pfc/other.cpp @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #include "pfc-lite.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3 #ifdef _MSC_VER
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4 #include <intrin.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5 #include <assert.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7 #ifndef _MSC_VER
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8 #include <signal.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 #include <stdlib.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12 #if defined(__ANDROID__)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13 #include <android/log.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 #include <math.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18 #include "string_base.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 #include "other.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 #include "bit_array_impl.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 #include "order_helper.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 #include "debug.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23 #include "byte_order.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24 #include "string_conv.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 #include "memalign.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 #include "platform-objects.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 #include "synchro.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 #include "pfc-fb2k-hooks.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 namespace pfc {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33 bool permutation_is_valid(t_size const * order, t_size count) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 bit_array_bittable found(count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35 for(t_size walk = 0; walk < count; ++walk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 const size_t v = order[walk];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 if (v >= count) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 if (found[v]) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 found.set(v,true);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43 void permutation_validate(t_size const * order, t_size count) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 if (!permutation_is_valid(order,count)) throw exception_invalid_permutation();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 t_size permutation_find_reverse(t_size const * order, t_size count, t_size value) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48 if (value >= count) return SIZE_MAX;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49 for(t_size walk = 0; walk < count; ++walk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 if (order[walk] == value) return walk;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 return SIZE_MAX;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 void create_move_item_permutation( size_t * order, size_t count, size_t from, size_t to ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 PFC_ASSERT( from < count );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57 PFC_ASSERT( to < count );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 for ( size_t w = 0; w < count; ++w ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 size_t i = w;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 if ( w == to ) i = from;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 else if ( w < to && w >= from ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 ++i;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 } else if ( w > to && w <= from ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 --i;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 order[w] = i;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 void create_move_items_permutation(t_size * p_output,t_size p_count,const bit_array & p_selection,int p_delta) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71 t_size * const order = p_output;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72 const t_size count = p_count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74 pfc::array_t<bool> selection; selection.set_size(p_count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76 for(t_size walk = 0; walk < count; ++walk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 order[walk] = walk;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78 selection[walk] = p_selection[walk];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 if (p_delta<0)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83 for(;p_delta<0;p_delta++)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 t_size idx;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86 for(idx=1;idx<count;idx++)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88 if (selection[idx] && !selection[idx-1])
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 pfc::swap_t(order[idx],order[idx-1]);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91 pfc::swap_t(selection[idx],selection[idx-1]);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98 for(;p_delta>0;p_delta--)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 t_size idx;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 for(idx=count-2;(int)idx>=0;idx--)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 if (selection[idx] && !selection[idx+1])
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 pfc::swap_t(order[idx],order[idx+1]);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106 pfc::swap_t(selection[idx],selection[idx+1]);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 bool create_drop_permutation(size_t * out, size_t itemCount, pfc::bit_array const & maskSelected, size_t insertMark ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113 const t_size count = itemCount;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 if (insertMark > count) insertMark = count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 t_size selBefore = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117 for(t_size walk = 0; walk < insertMark; ++walk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118 if (maskSelected[walk]) selBefore++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 insertMark -= selBefore;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123 pfc::array_t<t_size> permutation, selected, nonselected;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125 const t_size selcount = maskSelected.calc_count( true, 0, count );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126 selected.set_size(selcount); nonselected.set_size(count - selcount);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127 permutation.set_size(count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128 if (insertMark > nonselected.get_size()) insertMark = nonselected.get_size();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129 for(t_size walk = 0, swalk = 0, nwalk = 0; walk < count; ++walk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130 if (maskSelected[walk]) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131 selected[swalk++] = walk;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133 nonselected[nwalk++] = walk;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136 for(t_size walk = 0; walk < insertMark; ++walk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137 permutation[walk] = nonselected[walk];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139 for(t_size walk = 0; walk < selected.get_size(); ++walk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140 permutation[insertMark + walk] = selected[walk];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 for(t_size walk = insertMark; walk < nonselected.get_size(); ++walk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143 permutation[selected.get_size() + walk] = nonselected[walk];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
144 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
145 for(t_size walk = 0; walk < permutation.get_size(); ++walk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
146 if (permutation[walk] != walk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
147 memcpy(out, permutation.get_ptr(), count * sizeof(size_t));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
148 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155 bool is_identity(size_t const* order, size_t count) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156 for (size_t walk = 0; walk < count; ++walk) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157 if (order[walk] != walk) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163 void order_helper::g_swap(t_size * data,t_size ptr1,t_size ptr2)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
164 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
165 t_size temp = data[ptr1];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
166 data[ptr1] = data[ptr2];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
167 data[ptr2] = temp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
168 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
169
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
170
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
171 t_size order_helper::g_find_reverse(const t_size * order,t_size val)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
172 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
173 t_size prev = val, next = order[val];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
174 while(next != val)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
175 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
176 prev = next;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
177 next = order[next];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
178 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
179 return prev;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
180 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
181
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
182
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
183 void order_helper::g_reverse(t_size * order,t_size base,t_size count)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
184 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
185 t_size max = count>>1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
186 t_size n;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
187 t_size base2 = base+count-1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
188 for(n=0;n<max;n++)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
189 g_swap(order,base+n,base2-n);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
190 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
191
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
192
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
193 [[noreturn]] void pfc::crashImpl() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
194 #ifdef _WIN32
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
195 for (;;) { __debugbreak(); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
196 #else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
197 #if defined(__ANDROID__) && PFC_DEBUG
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
198 nixSleep(1);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
199 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
200 for ( ;; ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
201 *(volatile char*) 0 = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
202 raise(SIGINT);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
203 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
204 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
205 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
206
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
207 [[noreturn]] void pfc::crash() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
208 crashHook();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
209 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
210
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
211
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
212 void pfc::byteswap_raw(void * p_buffer,const t_size p_bytes) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
213 t_uint8 * ptr = (t_uint8*)p_buffer;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
214 t_size n;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
215 for(n=0;n<p_bytes>>1;n++) swap_t(ptr[n],ptr[p_bytes-n-1]);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
216 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
217
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
218 static pfc::debugLineReceiver * g_debugLineReceivers = nullptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
219
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
220 pfc::debugLineReceiver::debugLineReceiver() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
221 m_chain = g_debugLineReceivers;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
222 g_debugLineReceivers = this;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
223 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
224
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
225 void pfc::debugLineReceiver::dispatch( const char * msg ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
226 for( auto w = g_debugLineReceivers; w != nullptr; w = w->m_chain ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
227 w->onLine( msg );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
228 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
229 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
230 namespace pfc {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
231 void appleDebugLog( const char * str );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
232 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
233
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
234 void pfc::outputDebugLine(const char * msg) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
235 debugLineReceiver::dispatch( msg );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
236 #ifdef _WIN32
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
237 OutputDebugString(pfc::stringcvt::string_os_from_utf8(PFC_string_formatter() << msg << "\n") );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
238 #elif defined(__ANDROID__)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
239 __android_log_write(ANDROID_LOG_INFO, "Debug", msg);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
240 #elif defined(__APPLE__)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
241 appleDebugLog( msg );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
242 #else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
243 printf("%s\n", msg);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
244 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
245 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
246
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
247 void pfc::debugBreak() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
248 #ifdef _WIN32
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
249 __debugbreak();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
250 #else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
251 raise(SIGTRAP);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
252 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
253 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
254
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
255 #if PFC_DEBUG
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
256
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
257 #ifdef _WIN32
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
258 void pfc::myassert_win32(const wchar_t * _Message, const wchar_t *_File, unsigned _Line) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
259 if (IsDebuggerPresent()) debugBreak();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
260 PFC_DEBUGLOG << "PFC_ASSERT failure: " << _Message;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
261 PFC_DEBUGLOG << "PFC_ASSERT location: " << _File << " : " << _Line;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
262 _wassert(_Message,_File,_Line);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
263 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
264 #else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
265
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
266 void pfc::myassert(const char * _Message, const char *_File, unsigned _Line)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
267 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
268 PFC_DEBUGLOG << "Assert failure: \"" << _Message << "\" in: " << _File << " line " << _Line;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
269 debugBreak();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
270 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
271 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
272
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
273 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
274
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
275
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
276 t_uint64 pfc::pow_int(t_uint64 base, t_uint64 exp) noexcept {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
277 t_uint64 mul = base;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
278 t_uint64 val = 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
279 t_uint64 mask = 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
280 while(exp != 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
281 if (exp & mask) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
282 val *= mul;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
283 exp ^= mask;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
284 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
285 mul = mul * mul;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
286 mask <<= 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
287 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
288 return val;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
289 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
290
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
291 double pfc::exp_int( const double base, const int expS ) noexcept {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
292 // return pow(base, (double)v);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
293
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
294 bool neg;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
295 unsigned exp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
296 if (expS < 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
297 neg = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
298 exp = (unsigned) -expS;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
299 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
300 neg = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
301 exp = (unsigned) expS;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
302 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
303 double v = 1.0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
304 if (exp) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
305 double mul = base;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
306 for(;;) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
307 if (exp & 1) v *= mul;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
308 exp >>= 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
309 if (exp == 0) break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
310 mul *= mul;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
311 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
312 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
313 if (neg) v = 1.0 / v;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
314 return v;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
315 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
316
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
317
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
318 t_int32 pfc::rint32(double p_val) { return (t_int32)lround(p_val); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
319 t_int64 pfc::rint64(double p_val) { return (t_int64)llround(p_val); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
320
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
321
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
322 // mem_block class
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
323 namespace pfc {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
324 void mem_block::resize(size_t newSize) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
325 if (m_size != newSize) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
326 if (newSize == 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
327 free(m_ptr); m_ptr = nullptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
328 } else if (m_size == 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
329 m_ptr = malloc( newSize );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
330 if (m_ptr == nullptr) throw std::bad_alloc();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
331 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
332 auto newptr = realloc( m_ptr, newSize );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
333 if (newptr == nullptr) throw std::bad_alloc();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
334 m_ptr = newptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
335 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
336
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
337 m_size = newSize;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
338 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
339 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
340 void mem_block::clear() noexcept {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
341 free(m_ptr); m_ptr = nullptr; m_size = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
342 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
343 void mem_block::move( mem_block & other ) noexcept {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
344 clear();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
345 m_ptr = other.m_ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
346 m_size = other.m_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
347 other._clear();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
348 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
349 void mem_block::copy( mem_block const & other ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
350 const size_t size = other.size();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
351 resize( size );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
352 if (size > 0) memcpy(ptr(), other.ptr(), size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
353 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
354
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
355 // aligned alloc
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
356 void alignedAlloc( void* & m_ptr, size_t & m_size, size_t s, size_t alignBytes) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
357 if (s == m_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
358 // nothing to do
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
359 } else if (s == 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
360 alignedFree(m_ptr);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
361 m_ptr = NULL;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
362 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
363 void * ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
364 #ifdef _MSC_VER
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
365 if (m_ptr == NULL) ptr = _aligned_malloc(s, alignBytes);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
366 else ptr = _aligned_realloc(m_ptr, s, alignBytes);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
367 if ( ptr == NULL ) throw std::bad_alloc();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
368 #else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
369 #ifdef __ANDROID__
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
370 if ((ptr = memalign( alignBytes, s )) == NULL) throw std::bad_alloc();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
371 #else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
372 if (posix_memalign( &ptr, alignBytes, s ) < 0) throw std::bad_alloc();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
373 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
374 if (m_ptr != NULL) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
375 memcpy( ptr, m_ptr, min_t<size_t>( m_size, s ) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
376 alignedFree( m_ptr );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
377 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
378 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
379 m_ptr = ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
380 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
381 m_size = s;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
382 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
383
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
384 void* alignedAlloc( size_t s, size_t alignBytes ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
385 void * ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
386 #ifdef _MSC_VER
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
387 ptr = _aligned_malloc(s, alignBytes);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
388 if (ptr == nullptr) throw std::bad_alloc();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
389 #else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
390 #ifdef __ANDROID__
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
391 if ((ptr = memalign( alignBytes, s )) == NULL) throw std::bad_alloc();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
392 #else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
393 if (posix_memalign( &ptr, alignBytes, s ) < 0) throw std::bad_alloc();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
394 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
395 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
396 return ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
397 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
398
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
399 void alignedFree( void * ptr ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
400 #ifdef _MSC_VER
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
401 _aligned_free(ptr);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
402 #else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
403 free(ptr);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
404 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
405 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
406 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
407
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
408
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
409 #include "once.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
410
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
411 namespace pfc {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
412 #if PFC_CUSTOM_ONCE_FLAG
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
413 static pfc::once_flag_lite g_onceGuardGuard;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
414 static mutex * g_onceGuard;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
415
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
416 static mutex & onceGuard() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
417 call_once(g_onceGuardGuard, [] {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
418 g_onceGuard = new mutex();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
419 } );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
420 return * g_onceGuard;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
421 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
422
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
423 void call_once( once_flag & flag, std::function<void () > work ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
424
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
425 if ( flag.done ) return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
426
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
427 mutex & guard = onceGuard();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
428 for ( ;; ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
429 std::shared_ptr<pfc::event> waitFor;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
430 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
431 insync(guard);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
432 if ( flag.done ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
433 PFC_ASSERT( ! flag.inProgress );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
434 return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
435 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
436 if ( flag.inProgress ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
437 if ( ! flag.waitFor ) flag.waitFor = std::make_shared< event > ();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
438 waitFor = flag.waitFor;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
439 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
440 flag.inProgress = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
441 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
442 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
443
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
444 if ( waitFor ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
445 waitFor->wait_for( -1 );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
446 continue;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
447 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
448
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
449 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
450 work();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
451 } catch(...) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
452 insync( guard );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
453 PFC_ASSERT( ! flag.done );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
454 PFC_ASSERT( flag.inProgress );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
455 flag.inProgress = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
456 if ( flag.waitFor ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
457 flag.waitFor->set_state( true );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
458 flag.waitFor.reset();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
459 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
460 throw;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
461 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
462
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
463 // succeeded
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
464 insync( guard );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
465 PFC_ASSERT( ! flag.done );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
466 PFC_ASSERT( flag.inProgress );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
467 flag.inProgress = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
468 flag.done = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
469 if ( flag.waitFor ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
470 flag.waitFor->set_state( true );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
471 flag.waitFor.reset();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
472 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
473 return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
474 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
475 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
476 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
477 void call_once( once_flag_lite & flag, std::function<void ()> work ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
478 for ( ;; ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
479 if ( flag.done ) return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
480 if (! threadSafeInt::exchangeHere(flag.guard, 1)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
481 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
482 work();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
483 } catch(...) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
484 flag.guard = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
485 throw;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
486 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
487 flag.done = true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
488 return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
489 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
490 yield();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
491 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
492 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
493
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
494
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
495 #ifdef PFC_SET_THREAD_DESCRIPTION_EXTERNAL
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
496 static std::function<void (const char*)> g_setCurrentThreadDescription;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
497 void initSetCurrentThreadDescription( std::function<void (const char*)> f ) { g_setCurrentThreadDescription = f; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
498 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
499
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
500 void setCurrentThreadDescription( const char * msg ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
501 #ifdef __APPLE__
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
502 appleSetThreadDescription( msg );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
503 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
504
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
505 #ifdef PFC_WINDOWS_DESKTOP_APP
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
506 winSetThreadDescription(GetCurrentThread(), pfc::stringcvt::string_wide_from_utf8( msg ) );;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
507 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
508 #ifdef PFC_SET_THREAD_DESCRIPTION_EXTERNAL
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
509 if (g_setCurrentThreadDescription) g_setCurrentThreadDescription(msg);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
510 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
511 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
512 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
513
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
514