catboost 1.25.1 → 1.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DEPLOYMENT.md +22 -15
- package/README.md +37 -27
- package/binding.gyp +5 -7
- package/build_scripts/bootstrap.js +2 -1
- package/build_scripts/out/build.js +46 -68
- package/build_scripts/out/build_model.js +1 -1
- package/build_scripts/out/{build_ya.js → build_native.js} +1 -1
- package/build_scripts/out/ci.js +5 -5
- package/build_scripts/out/config.js +32 -18
- package/build_scripts/out/install.js +5 -3
- package/build_scripts/out/package_prepublish.js +1 -1
- package/build_scripts/out/packaging.js +1 -19
- package/build_scripts/out/run_tests.js +1 -1
- package/build_scripts/out/test.js +8 -3
- package/config.json +18 -11
- package/inc/catboost/libs/model_interface/c_api.h +349 -3
- package/lib/catboost.d.ts +65 -21
- package/package.json +4 -4
- package/src/api_helpers.cpp +100 -24
- package/src/api_helpers.h +8 -7
- package/src/api_module.cpp +1 -2
- package/src/model.cpp +483 -83
- package/src/model.h +24 -9
- package/inc/contrib/libs/cxxsupp/system_stl/include/stlfwd +0 -14
- package/inc/util/charset/recode_result.h +0 -9
- package/inc/util/charset/unicode_table.h +0 -123
- package/inc/util/charset/unidata.h +0 -421
- package/inc/util/charset/utf8.h +0 -384
- package/inc/util/charset/wide.h +0 -843
- package/inc/util/charset/wide_specific.h +0 -22
- package/inc/util/datetime/base.h +0 -669
- package/inc/util/datetime/constants.h +0 -7
- package/inc/util/datetime/cputimer.h +0 -124
- package/inc/util/datetime/parser.h +0 -292
- package/inc/util/datetime/systime.h +0 -47
- package/inc/util/datetime/uptime.h +0 -8
- package/inc/util/digest/city.h +0 -88
- package/inc/util/digest/fnv.h +0 -73
- package/inc/util/digest/multi.h +0 -14
- package/inc/util/digest/murmur.h +0 -57
- package/inc/util/digest/numeric.h +0 -86
- package/inc/util/digest/sequence.h +0 -48
- package/inc/util/draft/date.h +0 -129
- package/inc/util/draft/datetime.h +0 -184
- package/inc/util/draft/enum.h +0 -136
- package/inc/util/draft/holder_vector.h +0 -102
- package/inc/util/draft/ip.h +0 -131
- package/inc/util/draft/matrix.h +0 -108
- package/inc/util/draft/memory.h +0 -40
- package/inc/util/folder/dirent_win.h +0 -46
- package/inc/util/folder/dirut.h +0 -121
- package/inc/util/folder/filelist.h +0 -81
- package/inc/util/folder/fts.h +0 -108
- package/inc/util/folder/iterator.h +0 -109
- package/inc/util/folder/lstat_win.h +0 -20
- package/inc/util/folder/path.h +0 -225
- package/inc/util/folder/pathsplit.h +0 -113
- package/inc/util/folder/tempdir.h +0 -42
- package/inc/util/generic/adaptor.h +0 -134
- package/inc/util/generic/algorithm.h +0 -765
- package/inc/util/generic/array_ref.h +0 -282
- package/inc/util/generic/array_size.h +0 -24
- package/inc/util/generic/benchmark/vector_count_ctor/f.h +0 -9
- package/inc/util/generic/bitmap.h +0 -1115
- package/inc/util/generic/bitops.h +0 -459
- package/inc/util/generic/bt_exception.h +0 -24
- package/inc/util/generic/buffer.h +0 -232
- package/inc/util/generic/cast.h +0 -176
- package/inc/util/generic/deque.h +0 -24
- package/inc/util/generic/explicit_type.h +0 -42
- package/inc/util/generic/fastqueue.h +0 -55
- package/inc/util/generic/flags.h +0 -244
- package/inc/util/generic/function.h +0 -103
- package/inc/util/generic/fwd.h +0 -171
- package/inc/util/generic/guid.h +0 -61
- package/inc/util/generic/hash.h +0 -2032
- package/inc/util/generic/hash_primes.h +0 -140
- package/inc/util/generic/hash_set.h +0 -490
- package/inc/util/generic/hide_ptr.h +0 -3
- package/inc/util/generic/intrlist.h +0 -876
- package/inc/util/generic/is_in.h +0 -53
- package/inc/util/generic/iterator.h +0 -137
- package/inc/util/generic/iterator_range.h +0 -105
- package/inc/util/generic/lazy_value.h +0 -66
- package/inc/util/generic/list.h +0 -22
- package/inc/util/generic/map.h +0 -44
- package/inc/util/generic/mapfindptr.h +0 -60
- package/inc/util/generic/maybe.h +0 -713
- package/inc/util/generic/maybe_traits.h +0 -164
- package/inc/util/generic/mem_copy.h +0 -55
- package/inc/util/generic/noncopyable.h +0 -38
- package/inc/util/generic/object_counter.h +0 -53
- package/inc/util/generic/ptr.h +0 -1113
- package/inc/util/generic/queue.h +0 -57
- package/inc/util/generic/refcount.h +0 -162
- package/inc/util/generic/reserve.h +0 -11
- package/inc/util/generic/scope.h +0 -65
- package/inc/util/generic/serialized_enum.h +0 -406
- package/inc/util/generic/set.h +0 -42
- package/inc/util/generic/singleton.h +0 -136
- package/inc/util/generic/size_literals.h +0 -65
- package/inc/util/generic/stack.h +0 -18
- package/inc/util/generic/store_policy.h +0 -120
- package/inc/util/generic/strbase.h +0 -612
- package/inc/util/generic/strbuf.h +0 -552
- package/inc/util/generic/strfcpy.h +0 -17
- package/inc/util/generic/string.h +0 -1572
- package/inc/util/generic/string_hash.h +0 -21
- package/inc/util/generic/string_ut.h +0 -1175
- package/inc/util/generic/type_name.h +0 -34
- package/inc/util/generic/typelist.h +0 -114
- package/inc/util/generic/typetraits.h +0 -325
- package/inc/util/generic/utility.h +0 -132
- package/inc/util/generic/va_args.h +0 -400
- package/inc/util/generic/variant.h +0 -631
- package/inc/util/generic/variant_traits.h +0 -171
- package/inc/util/generic/vector.h +0 -119
- package/inc/util/generic/xrange.h +0 -258
- package/inc/util/generic/yexception.h +0 -212
- package/inc/util/generic/yexception_ut.h +0 -14
- package/inc/util/generic/ylimits.h +0 -92
- package/inc/util/generic/ymath.h +0 -206
- package/inc/util/memory/addstorage.h +0 -93
- package/inc/util/memory/alloc.h +0 -27
- package/inc/util/memory/blob.h +0 -296
- package/inc/util/memory/mmapalloc.h +0 -8
- package/inc/util/memory/pool.h +0 -432
- package/inc/util/memory/segmented_string_pool.h +0 -194
- package/inc/util/memory/segpool_alloc.h +0 -118
- package/inc/util/memory/smallobj.h +0 -141
- package/inc/util/memory/tempbuf.h +0 -111
- package/inc/util/network/address.h +0 -136
- package/inc/util/network/endpoint.h +0 -61
- package/inc/util/network/hostip.h +0 -16
- package/inc/util/network/init.h +0 -60
- package/inc/util/network/interface.h +0 -17
- package/inc/util/network/iovec.h +0 -65
- package/inc/util/network/ip.h +0 -116
- package/inc/util/network/nonblock.h +0 -8
- package/inc/util/network/pair.h +0 -9
- package/inc/util/network/poller.h +0 -58
- package/inc/util/network/pollerimpl.h +0 -707
- package/inc/util/network/sock.h +0 -608
- package/inc/util/network/socket.h +0 -421
- package/inc/util/random/common_ops.h +0 -130
- package/inc/util/random/easy.h +0 -47
- package/inc/util/random/entropy.h +0 -21
- package/inc/util/random/fast.h +0 -101
- package/inc/util/random/init_atfork.h +0 -3
- package/inc/util/random/lcg_engine.h +0 -66
- package/inc/util/random/mersenne.h +0 -46
- package/inc/util/random/mersenne32.h +0 -50
- package/inc/util/random/mersenne64.h +0 -50
- package/inc/util/random/normal.h +0 -38
- package/inc/util/random/random.h +0 -30
- package/inc/util/random/shuffle.h +0 -39
- package/inc/util/str_stl.h +0 -266
- package/inc/util/stream/aligned.h +0 -99
- package/inc/util/stream/buffer.h +0 -119
- package/inc/util/stream/buffered.h +0 -225
- package/inc/util/stream/debug.h +0 -53
- package/inc/util/stream/direct_io.h +0 -43
- package/inc/util/stream/file.h +0 -108
- package/inc/util/stream/format.h +0 -444
- package/inc/util/stream/fwd.h +0 -100
- package/inc/util/stream/hex.h +0 -8
- package/inc/util/stream/holder.h +0 -44
- package/inc/util/stream/input.h +0 -273
- package/inc/util/stream/labeled.h +0 -19
- package/inc/util/stream/length.h +0 -100
- package/inc/util/stream/mem.h +0 -255
- package/inc/util/stream/multi.h +0 -32
- package/inc/util/stream/null.h +0 -61
- package/inc/util/stream/output.h +0 -304
- package/inc/util/stream/pipe.h +0 -112
- package/inc/util/stream/printf.h +0 -25
- package/inc/util/stream/str.h +0 -207
- package/inc/util/stream/tee.h +0 -28
- package/inc/util/stream/tempbuf.h +0 -21
- package/inc/util/stream/tokenizer.h +0 -214
- package/inc/util/stream/trace.h +0 -60
- package/inc/util/stream/walk.h +0 -35
- package/inc/util/stream/zerocopy.h +0 -91
- package/inc/util/stream/zerocopy_output.h +0 -57
- package/inc/util/stream/zlib.h +0 -173
- package/inc/util/string/ascii.h +0 -236
- package/inc/util/string/builder.h +0 -39
- package/inc/util/string/cast.h +0 -347
- package/inc/util/string/cstriter.h +0 -14
- package/inc/util/string/escape.h +0 -70
- package/inc/util/string/hex.h +0 -59
- package/inc/util/string/join.h +0 -194
- package/inc/util/string/printf.h +0 -13
- package/inc/util/string/reverse.h +0 -16
- package/inc/util/string/split.h +0 -1080
- package/inc/util/string/strip.h +0 -257
- package/inc/util/string/strspn.h +0 -65
- package/inc/util/string/subst.h +0 -56
- package/inc/util/string/type.h +0 -50
- package/inc/util/string/util.h +0 -195
- package/inc/util/string/vector.h +0 -132
- package/inc/util/system/align.h +0 -50
- package/inc/util/system/atexit.h +0 -22
- package/inc/util/system/atomic.h +0 -51
- package/inc/util/system/atomic_gcc.h +0 -90
- package/inc/util/system/atomic_ops.h +0 -189
- package/inc/util/system/atomic_win.h +0 -114
- package/inc/util/system/backtrace.h +0 -39
- package/inc/util/system/byteorder.h +0 -186
- package/inc/util/system/compat.h +0 -84
- package/inc/util/system/compiler.h +0 -620
- package/inc/util/system/condvar.h +0 -71
- package/inc/util/system/context.h +0 -181
- package/inc/util/system/context_aarch64.h +0 -8
- package/inc/util/system/context_i686.h +0 -9
- package/inc/util/system/context_x86.h +0 -12
- package/inc/util/system/context_x86_64.h +0 -7
- package/inc/util/system/cpu_id.h +0 -159
- package/inc/util/system/daemon.h +0 -28
- package/inc/util/system/datetime.h +0 -98
- package/inc/util/system/defaults.h +0 -149
- package/inc/util/system/demangle.h +0 -5
- package/inc/util/system/demangle_impl.h +0 -23
- package/inc/util/system/direct_io.h +0 -71
- package/inc/util/system/dynlib.h +0 -119
- package/inc/util/system/env.h +0 -32
- package/inc/util/system/error.h +0 -95
- package/inc/util/system/event.h +0 -122
- package/inc/util/system/execpath.h +0 -17
- package/inc/util/system/fasttime.h +0 -6
- package/inc/util/system/fhandle.h +0 -27
- package/inc/util/system/file.h +0 -210
- package/inc/util/system/file_lock.h +0 -34
- package/inc/util/system/filemap.h +0 -383
- package/inc/util/system/flock.h +0 -35
- package/inc/util/system/fs.h +0 -156
- package/inc/util/system/fs_win.h +0 -29
- package/inc/util/system/fstat.h +0 -46
- package/inc/util/system/getpid.h +0 -12
- package/inc/util/system/guard.h +0 -179
- package/inc/util/system/hi_lo.h +0 -139
- package/inc/util/system/hostname.h +0 -10
- package/inc/util/system/hp_timer.h +0 -36
- package/inc/util/system/info.h +0 -12
- package/inc/util/system/interrupt_signals.h +0 -22
- package/inc/util/system/madvise.h +0 -30
- package/inc/util/system/maxlen.h +0 -32
- package/inc/util/system/mem_info.h +0 -18
- package/inc/util/system/mincore.h +0 -38
- package/inc/util/system/mktemp.h +0 -11
- package/inc/util/system/mlock.h +0 -43
- package/inc/util/system/mutex.h +0 -67
- package/inc/util/system/nice.h +0 -3
- package/inc/util/system/pipe.h +0 -90
- package/inc/util/system/platform.h +0 -246
- package/inc/util/system/progname.h +0 -13
- package/inc/util/system/protect.h +0 -25
- package/inc/util/system/rusage.h +0 -26
- package/inc/util/system/rwlock.h +0 -78
- package/inc/util/system/sanitizers.h +0 -122
- package/inc/util/system/sem.h +0 -41
- package/inc/util/system/shellcommand.h +0 -472
- package/inc/util/system/shmat.h +0 -32
- package/inc/util/system/sigset.h +0 -78
- package/inc/util/system/spin_wait.h +0 -10
- package/inc/util/system/spinlock.h +0 -121
- package/inc/util/system/src_location.h +0 -25
- package/inc/util/system/src_root.h +0 -68
- package/inc/util/system/sys_alloc.h +0 -43
- package/inc/util/system/sysstat.h +0 -52
- package/inc/util/system/tempfile.h +0 -34
- package/inc/util/system/thread.h +0 -167
- package/inc/util/system/tls.h +0 -307
- package/inc/util/system/types.h +0 -119
- package/inc/util/system/unaligned_mem.h +0 -67
- package/inc/util/system/user.h +0 -5
- package/inc/util/system/utime.h +0 -6
- package/inc/util/system/valgrind.h +0 -48
- package/inc/util/system/winint.h +0 -43
- package/inc/util/system/yassert.h +0 -121
- package/inc/util/system/yield.h +0 -4
- package/inc/util/thread/factory.h +0 -65
- package/inc/util/thread/fwd.h +0 -30
- package/inc/util/thread/lfqueue.h +0 -406
- package/inc/util/thread/lfstack.h +0 -188
- package/inc/util/thread/pool.h +0 -388
- package/inc/util/thread/singleton.h +0 -42
- package/inc/util/ysafeptr.h +0 -427
- package/inc/util/ysaveload.h +0 -700
|
@@ -1,406 +0,0 @@
|
|
|
1
|
-
#pragma once
|
|
2
|
-
|
|
3
|
-
#include "fwd.h"
|
|
4
|
-
|
|
5
|
-
#include <util/generic/ptr.h>
|
|
6
|
-
#include <util/system/atomic.h>
|
|
7
|
-
#include <util/system/yassert.h>
|
|
8
|
-
#include "lfstack.h"
|
|
9
|
-
|
|
10
|
-
struct TDefaultLFCounter {
|
|
11
|
-
template <class T>
|
|
12
|
-
void IncCount(const T& data) {
|
|
13
|
-
(void)data;
|
|
14
|
-
}
|
|
15
|
-
template <class T>
|
|
16
|
-
void DecCount(const T& data) {
|
|
17
|
-
(void)data;
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
// @brief lockfree queue
|
|
22
|
-
// @tparam T - the queue element, should be movable
|
|
23
|
-
// @tparam TCounter, a observer class to count number of items in queue
|
|
24
|
-
// be carifull, IncCount and DecCount can be called on a moved object and
|
|
25
|
-
// it is TCounter class responsibility to check validity of passed object
|
|
26
|
-
template <class T, class TCounter>
|
|
27
|
-
class TLockFreeQueue: public TNonCopyable {
|
|
28
|
-
struct TListNode {
|
|
29
|
-
template <typename U>
|
|
30
|
-
TListNode(U&& u, TListNode* next)
|
|
31
|
-
: Next(next)
|
|
32
|
-
, Data(std::forward<U>(u))
|
|
33
|
-
{
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
template <typename U>
|
|
37
|
-
explicit TListNode(U&& u)
|
|
38
|
-
: Data(std::forward<U>(u))
|
|
39
|
-
{
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
TListNode* volatile Next;
|
|
43
|
-
T Data;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
// using inheritance to be able to use 0 bytes for TCounter when we don't need one
|
|
47
|
-
struct TRootNode: public TCounter {
|
|
48
|
-
TListNode* volatile PushQueue;
|
|
49
|
-
TListNode* volatile PopQueue;
|
|
50
|
-
TListNode* volatile ToDelete;
|
|
51
|
-
TRootNode* volatile NextFree;
|
|
52
|
-
|
|
53
|
-
TRootNode()
|
|
54
|
-
: PushQueue(nullptr)
|
|
55
|
-
, PopQueue(nullptr)
|
|
56
|
-
, ToDelete(nullptr)
|
|
57
|
-
, NextFree(nullptr)
|
|
58
|
-
{
|
|
59
|
-
}
|
|
60
|
-
void CopyCounter(TRootNode* x) {
|
|
61
|
-
*(TCounter*)this = *(TCounter*)x;
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
static void EraseList(TListNode* n) {
|
|
66
|
-
while (n) {
|
|
67
|
-
TListNode* keepNext = AtomicGet(n->Next);
|
|
68
|
-
delete n;
|
|
69
|
-
n = keepNext;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
alignas(64) TRootNode* volatile JobQueue;
|
|
74
|
-
alignas(64) volatile TAtomic FreememCounter;
|
|
75
|
-
alignas(64) volatile TAtomic FreeingTaskCounter;
|
|
76
|
-
alignas(64) TRootNode* volatile FreePtr;
|
|
77
|
-
|
|
78
|
-
void TryToFreeAsyncMemory() {
|
|
79
|
-
TAtomic keepCounter = AtomicAdd(FreeingTaskCounter, 0);
|
|
80
|
-
TRootNode* current = AtomicGet(FreePtr);
|
|
81
|
-
if (current == nullptr)
|
|
82
|
-
return;
|
|
83
|
-
if (AtomicAdd(FreememCounter, 0) == 1) {
|
|
84
|
-
// we are the last thread, try to cleanup
|
|
85
|
-
// check if another thread have cleaned up
|
|
86
|
-
if (keepCounter != AtomicAdd(FreeingTaskCounter, 0)) {
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
if (AtomicCas(&FreePtr, (TRootNode*)nullptr, current)) {
|
|
90
|
-
// free list
|
|
91
|
-
while (current) {
|
|
92
|
-
TRootNode* p = AtomicGet(current->NextFree);
|
|
93
|
-
EraseList(AtomicGet(current->ToDelete));
|
|
94
|
-
delete current;
|
|
95
|
-
current = p;
|
|
96
|
-
}
|
|
97
|
-
AtomicAdd(FreeingTaskCounter, 1);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
void AsyncRef() {
|
|
102
|
-
AtomicAdd(FreememCounter, 1);
|
|
103
|
-
}
|
|
104
|
-
void AsyncUnref() {
|
|
105
|
-
TryToFreeAsyncMemory();
|
|
106
|
-
AtomicAdd(FreememCounter, -1);
|
|
107
|
-
}
|
|
108
|
-
void AsyncDel(TRootNode* toDelete, TListNode* lst) {
|
|
109
|
-
AtomicSet(toDelete->ToDelete, lst);
|
|
110
|
-
for (;;) {
|
|
111
|
-
AtomicSet(toDelete->NextFree, AtomicGet(FreePtr));
|
|
112
|
-
if (AtomicCas(&FreePtr, toDelete, AtomicGet(toDelete->NextFree)))
|
|
113
|
-
break;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
void AsyncUnref(TRootNode* toDelete, TListNode* lst) {
|
|
117
|
-
TryToFreeAsyncMemory();
|
|
118
|
-
if (AtomicAdd(FreememCounter, -1) == 0) {
|
|
119
|
-
// no other operations in progress, can safely reclaim memory
|
|
120
|
-
EraseList(lst);
|
|
121
|
-
delete toDelete;
|
|
122
|
-
} else {
|
|
123
|
-
// Dequeue()s in progress, put node to free list
|
|
124
|
-
AsyncDel(toDelete, lst);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
struct TListInvertor {
|
|
129
|
-
TListNode* Copy;
|
|
130
|
-
TListNode* Tail;
|
|
131
|
-
TListNode* PrevFirst;
|
|
132
|
-
|
|
133
|
-
TListInvertor()
|
|
134
|
-
: Copy(nullptr)
|
|
135
|
-
, Tail(nullptr)
|
|
136
|
-
, PrevFirst(nullptr)
|
|
137
|
-
{
|
|
138
|
-
}
|
|
139
|
-
~TListInvertor() {
|
|
140
|
-
EraseList(Copy);
|
|
141
|
-
}
|
|
142
|
-
void CopyWasUsed() {
|
|
143
|
-
Copy = nullptr;
|
|
144
|
-
Tail = nullptr;
|
|
145
|
-
PrevFirst = nullptr;
|
|
146
|
-
}
|
|
147
|
-
void DoCopy(TListNode* ptr) {
|
|
148
|
-
TListNode* newFirst = ptr;
|
|
149
|
-
TListNode* newCopy = nullptr;
|
|
150
|
-
TListNode* newTail = nullptr;
|
|
151
|
-
while (ptr) {
|
|
152
|
-
if (ptr == PrevFirst) {
|
|
153
|
-
// short cut, we have copied this part already
|
|
154
|
-
AtomicSet(Tail->Next, newCopy);
|
|
155
|
-
newCopy = Copy;
|
|
156
|
-
Copy = nullptr; // do not destroy prev try
|
|
157
|
-
if (!newTail)
|
|
158
|
-
newTail = Tail; // tried to invert same list
|
|
159
|
-
break;
|
|
160
|
-
}
|
|
161
|
-
TListNode* newElem = new TListNode(ptr->Data, newCopy);
|
|
162
|
-
newCopy = newElem;
|
|
163
|
-
ptr = AtomicGet(ptr->Next);
|
|
164
|
-
if (!newTail)
|
|
165
|
-
newTail = newElem;
|
|
166
|
-
}
|
|
167
|
-
EraseList(Copy); // copy was useless
|
|
168
|
-
Copy = newCopy;
|
|
169
|
-
PrevFirst = newFirst;
|
|
170
|
-
Tail = newTail;
|
|
171
|
-
}
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
void EnqueueImpl(TListNode* head, TListNode* tail) {
|
|
175
|
-
TRootNode* newRoot = new TRootNode;
|
|
176
|
-
AsyncRef();
|
|
177
|
-
AtomicSet(newRoot->PushQueue, head);
|
|
178
|
-
for (;;) {
|
|
179
|
-
TRootNode* curRoot = AtomicGet(JobQueue);
|
|
180
|
-
AtomicSet(tail->Next, AtomicGet(curRoot->PushQueue));
|
|
181
|
-
AtomicSet(newRoot->PopQueue, AtomicGet(curRoot->PopQueue));
|
|
182
|
-
newRoot->CopyCounter(curRoot);
|
|
183
|
-
|
|
184
|
-
for (TListNode* node = head;; node = AtomicGet(node->Next)) {
|
|
185
|
-
newRoot->IncCount(node->Data);
|
|
186
|
-
if (node == tail)
|
|
187
|
-
break;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
if (AtomicCas(&JobQueue, newRoot, curRoot)) {
|
|
191
|
-
AsyncUnref(curRoot, nullptr);
|
|
192
|
-
break;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
template <typename TCollection>
|
|
198
|
-
static void FillCollection(TListNode* lst, TCollection* res) {
|
|
199
|
-
while (lst) {
|
|
200
|
-
res->emplace_back(std::move(lst->Data));
|
|
201
|
-
lst = AtomicGet(lst->Next);
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/** Traverses a given list simultaneously creating its inversed version.
|
|
206
|
-
* After that, fills a collection with a reversed version and returns the last visited lst's node.
|
|
207
|
-
*/
|
|
208
|
-
template <typename TCollection>
|
|
209
|
-
static TListNode* FillCollectionReverse(TListNode* lst, TCollection* res) {
|
|
210
|
-
if (!lst) {
|
|
211
|
-
return nullptr;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
TListNode* newCopy = nullptr;
|
|
215
|
-
do {
|
|
216
|
-
TListNode* newElem = new TListNode(std::move(lst->Data), newCopy);
|
|
217
|
-
newCopy = newElem;
|
|
218
|
-
lst = AtomicGet(lst->Next);
|
|
219
|
-
} while (lst);
|
|
220
|
-
|
|
221
|
-
FillCollection(newCopy, res);
|
|
222
|
-
EraseList(newCopy);
|
|
223
|
-
|
|
224
|
-
return lst;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
public:
|
|
228
|
-
TLockFreeQueue()
|
|
229
|
-
: JobQueue(new TRootNode)
|
|
230
|
-
, FreememCounter(0)
|
|
231
|
-
, FreeingTaskCounter(0)
|
|
232
|
-
, FreePtr(nullptr)
|
|
233
|
-
{
|
|
234
|
-
}
|
|
235
|
-
~TLockFreeQueue() {
|
|
236
|
-
AsyncRef();
|
|
237
|
-
AsyncUnref(); // should free FreeList
|
|
238
|
-
EraseList(JobQueue->PushQueue);
|
|
239
|
-
EraseList(JobQueue->PopQueue);
|
|
240
|
-
delete JobQueue;
|
|
241
|
-
}
|
|
242
|
-
template <typename U>
|
|
243
|
-
void Enqueue(U&& data) {
|
|
244
|
-
TListNode* newNode = new TListNode(std::forward<U>(data));
|
|
245
|
-
EnqueueImpl(newNode, newNode);
|
|
246
|
-
}
|
|
247
|
-
void Enqueue(T&& data) {
|
|
248
|
-
TListNode* newNode = new TListNode(std::move(data));
|
|
249
|
-
EnqueueImpl(newNode, newNode);
|
|
250
|
-
}
|
|
251
|
-
void Enqueue(const T& data) {
|
|
252
|
-
TListNode* newNode = new TListNode(data);
|
|
253
|
-
EnqueueImpl(newNode, newNode);
|
|
254
|
-
}
|
|
255
|
-
template <typename TCollection>
|
|
256
|
-
void EnqueueAll(const TCollection& data) {
|
|
257
|
-
EnqueueAll(data.begin(), data.end());
|
|
258
|
-
}
|
|
259
|
-
template <typename TIter>
|
|
260
|
-
void EnqueueAll(TIter dataBegin, TIter dataEnd) {
|
|
261
|
-
if (dataBegin == dataEnd)
|
|
262
|
-
return;
|
|
263
|
-
|
|
264
|
-
TIter i = dataBegin;
|
|
265
|
-
TListNode* volatile node = new TListNode(*i);
|
|
266
|
-
TListNode* volatile tail = node;
|
|
267
|
-
|
|
268
|
-
for (++i; i != dataEnd; ++i) {
|
|
269
|
-
TListNode* nextNode = node;
|
|
270
|
-
node = new TListNode(*i, nextNode);
|
|
271
|
-
}
|
|
272
|
-
EnqueueImpl(node, tail);
|
|
273
|
-
}
|
|
274
|
-
bool Dequeue(T* data) {
|
|
275
|
-
TRootNode* newRoot = nullptr;
|
|
276
|
-
TListInvertor listInvertor;
|
|
277
|
-
AsyncRef();
|
|
278
|
-
for (;;) {
|
|
279
|
-
TRootNode* curRoot = AtomicGet(JobQueue);
|
|
280
|
-
TListNode* tail = AtomicGet(curRoot->PopQueue);
|
|
281
|
-
if (tail) {
|
|
282
|
-
// has elems to pop
|
|
283
|
-
if (!newRoot)
|
|
284
|
-
newRoot = new TRootNode;
|
|
285
|
-
|
|
286
|
-
AtomicSet(newRoot->PushQueue, AtomicGet(curRoot->PushQueue));
|
|
287
|
-
AtomicSet(newRoot->PopQueue, AtomicGet(tail->Next));
|
|
288
|
-
newRoot->CopyCounter(curRoot);
|
|
289
|
-
newRoot->DecCount(tail->Data);
|
|
290
|
-
Y_ASSERT(AtomicGet(curRoot->PopQueue) == tail);
|
|
291
|
-
if (AtomicCas(&JobQueue, newRoot, curRoot)) {
|
|
292
|
-
*data = std::move(tail->Data);
|
|
293
|
-
AtomicSet(tail->Next, nullptr);
|
|
294
|
-
AsyncUnref(curRoot, tail);
|
|
295
|
-
return true;
|
|
296
|
-
}
|
|
297
|
-
continue;
|
|
298
|
-
}
|
|
299
|
-
if (AtomicGet(curRoot->PushQueue) == nullptr) {
|
|
300
|
-
delete newRoot;
|
|
301
|
-
AsyncUnref();
|
|
302
|
-
return false; // no elems to pop
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
if (!newRoot)
|
|
306
|
-
newRoot = new TRootNode;
|
|
307
|
-
AtomicSet(newRoot->PushQueue, nullptr);
|
|
308
|
-
listInvertor.DoCopy(AtomicGet(curRoot->PushQueue));
|
|
309
|
-
AtomicSet(newRoot->PopQueue, listInvertor.Copy);
|
|
310
|
-
newRoot->CopyCounter(curRoot);
|
|
311
|
-
Y_ASSERT(AtomicGet(curRoot->PopQueue) == nullptr);
|
|
312
|
-
if (AtomicCas(&JobQueue, newRoot, curRoot)) {
|
|
313
|
-
newRoot = nullptr;
|
|
314
|
-
listInvertor.CopyWasUsed();
|
|
315
|
-
AsyncDel(curRoot, AtomicGet(curRoot->PushQueue));
|
|
316
|
-
} else {
|
|
317
|
-
AtomicSet(newRoot->PopQueue, nullptr);
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
template <typename TCollection>
|
|
322
|
-
void DequeueAll(TCollection* res) {
|
|
323
|
-
AsyncRef();
|
|
324
|
-
|
|
325
|
-
TRootNode* newRoot = new TRootNode;
|
|
326
|
-
TRootNode* curRoot;
|
|
327
|
-
do {
|
|
328
|
-
curRoot = AtomicGet(JobQueue);
|
|
329
|
-
} while (!AtomicCas(&JobQueue, newRoot, curRoot));
|
|
330
|
-
|
|
331
|
-
FillCollection(curRoot->PopQueue, res);
|
|
332
|
-
|
|
333
|
-
TListNode* toDeleteHead = curRoot->PushQueue;
|
|
334
|
-
TListNode* toDeleteTail = FillCollectionReverse(curRoot->PushQueue, res);
|
|
335
|
-
AtomicSet(curRoot->PushQueue, nullptr);
|
|
336
|
-
|
|
337
|
-
if (toDeleteTail) {
|
|
338
|
-
toDeleteTail->Next = curRoot->PopQueue;
|
|
339
|
-
} else {
|
|
340
|
-
toDeleteTail = curRoot->PopQueue;
|
|
341
|
-
}
|
|
342
|
-
AtomicSet(curRoot->PopQueue, nullptr);
|
|
343
|
-
|
|
344
|
-
AsyncUnref(curRoot, toDeleteHead);
|
|
345
|
-
}
|
|
346
|
-
bool IsEmpty() {
|
|
347
|
-
AsyncRef();
|
|
348
|
-
TRootNode* curRoot = AtomicGet(JobQueue);
|
|
349
|
-
bool res = AtomicGet(curRoot->PushQueue) == nullptr && AtomicGet(curRoot->PopQueue) == nullptr;
|
|
350
|
-
AsyncUnref();
|
|
351
|
-
return res;
|
|
352
|
-
}
|
|
353
|
-
TCounter GetCounter() {
|
|
354
|
-
AsyncRef();
|
|
355
|
-
TRootNode* curRoot = AtomicGet(JobQueue);
|
|
356
|
-
TCounter res = *(TCounter*)curRoot;
|
|
357
|
-
AsyncUnref();
|
|
358
|
-
return res;
|
|
359
|
-
}
|
|
360
|
-
};
|
|
361
|
-
|
|
362
|
-
template <class T, class TCounter>
|
|
363
|
-
class TAutoLockFreeQueue {
|
|
364
|
-
public:
|
|
365
|
-
using TRef = THolder<T>;
|
|
366
|
-
|
|
367
|
-
inline ~TAutoLockFreeQueue() {
|
|
368
|
-
TRef tmp;
|
|
369
|
-
|
|
370
|
-
while (Dequeue(&tmp)) {
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
inline bool Dequeue(TRef* t) {
|
|
375
|
-
T* res = nullptr;
|
|
376
|
-
|
|
377
|
-
if (Queue.Dequeue(&res)) {
|
|
378
|
-
t->Reset(res);
|
|
379
|
-
|
|
380
|
-
return true;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
return false;
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
inline void Enqueue(TRef& t) {
|
|
387
|
-
Queue.Enqueue(t.Get());
|
|
388
|
-
Y_UNUSED(t.Release());
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
inline void Enqueue(TRef&& t) {
|
|
392
|
-
Queue.Enqueue(t.Get());
|
|
393
|
-
Y_UNUSED(t.Release());
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
inline bool IsEmpty() {
|
|
397
|
-
return Queue.IsEmpty();
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
inline TCounter GetCounter() {
|
|
401
|
-
return Queue.GetCounter();
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
private:
|
|
405
|
-
TLockFreeQueue<T*, TCounter> Queue;
|
|
406
|
-
};
|
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
#pragma once
|
|
2
|
-
|
|
3
|
-
#include <util/generic/noncopyable.h>
|
|
4
|
-
#include <util/system/atomic.h>
|
|
5
|
-
|
|
6
|
-
//////////////////////////////
|
|
7
|
-
// lock free lifo stack
|
|
8
|
-
template <class T>
|
|
9
|
-
class TLockFreeStack : TNonCopyable {
|
|
10
|
-
struct TNode {
|
|
11
|
-
T Value;
|
|
12
|
-
TNode* Next;
|
|
13
|
-
|
|
14
|
-
TNode() = default;
|
|
15
|
-
|
|
16
|
-
template<class U>
|
|
17
|
-
explicit TNode(U&& val)
|
|
18
|
-
: Value(std::forward<U>(val))
|
|
19
|
-
, Next(nullptr)
|
|
20
|
-
{
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
TNode* Head;
|
|
25
|
-
TNode* FreePtr;
|
|
26
|
-
TAtomic DequeueCount;
|
|
27
|
-
|
|
28
|
-
void TryToFreeMemory() {
|
|
29
|
-
TNode* current = AtomicGet(FreePtr);
|
|
30
|
-
if (!current)
|
|
31
|
-
return;
|
|
32
|
-
if (AtomicAdd(DequeueCount, 0) == 1) {
|
|
33
|
-
// node current is in free list, we are the last thread so try to cleanup
|
|
34
|
-
if (AtomicCas(&FreePtr, (TNode*)nullptr, current))
|
|
35
|
-
EraseList(current);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
void EraseList(TNode* volatile p) {
|
|
39
|
-
while (p) {
|
|
40
|
-
TNode* next = p->Next;
|
|
41
|
-
delete p;
|
|
42
|
-
p = next;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
void EnqueueImpl(TNode* volatile head, TNode* volatile tail) {
|
|
46
|
-
for (;;) {
|
|
47
|
-
tail->Next = AtomicGet(Head);
|
|
48
|
-
if (AtomicCas(&Head, head, tail->Next))
|
|
49
|
-
break;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
template <class U>
|
|
53
|
-
void EnqueueImpl(U&& u) {
|
|
54
|
-
TNode* volatile node = new TNode(std::forward<U>(u));
|
|
55
|
-
EnqueueImpl(node, node);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
public:
|
|
59
|
-
TLockFreeStack()
|
|
60
|
-
: Head(nullptr)
|
|
61
|
-
, FreePtr(nullptr)
|
|
62
|
-
, DequeueCount(0)
|
|
63
|
-
{
|
|
64
|
-
}
|
|
65
|
-
~TLockFreeStack() {
|
|
66
|
-
EraseList(Head);
|
|
67
|
-
EraseList(FreePtr);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
void Enqueue(const T& t) {
|
|
71
|
-
EnqueueImpl(t);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
void Enqueue(T&& t) {
|
|
75
|
-
EnqueueImpl(std::move(t));
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
template <typename TCollection>
|
|
79
|
-
void EnqueueAll(const TCollection& data) {
|
|
80
|
-
EnqueueAll(data.begin(), data.end());
|
|
81
|
-
}
|
|
82
|
-
template <typename TIter>
|
|
83
|
-
void EnqueueAll(TIter dataBegin, TIter dataEnd) {
|
|
84
|
-
if (dataBegin == dataEnd) {
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
TIter i = dataBegin;
|
|
88
|
-
TNode* volatile node = new TNode(*i);
|
|
89
|
-
TNode* volatile tail = node;
|
|
90
|
-
|
|
91
|
-
for (++i; i != dataEnd; ++i) {
|
|
92
|
-
TNode* nextNode = node;
|
|
93
|
-
node = new TNode(*i);
|
|
94
|
-
node->Next = nextNode;
|
|
95
|
-
}
|
|
96
|
-
EnqueueImpl(node, tail);
|
|
97
|
-
}
|
|
98
|
-
bool Dequeue(T* res) {
|
|
99
|
-
AtomicAdd(DequeueCount, 1);
|
|
100
|
-
for (TNode* current = AtomicGet(Head); current; current = AtomicGet(Head)) {
|
|
101
|
-
if (AtomicCas(&Head, AtomicGet(current->Next), current)) {
|
|
102
|
-
*res = std::move(current->Value);
|
|
103
|
-
// delete current; // ABA problem
|
|
104
|
-
// even more complex node deletion
|
|
105
|
-
TryToFreeMemory();
|
|
106
|
-
if (AtomicAdd(DequeueCount, -1) == 0) {
|
|
107
|
-
// no other Dequeue()s, can safely reclaim memory
|
|
108
|
-
delete current;
|
|
109
|
-
} else {
|
|
110
|
-
// Dequeue()s in progress, put node to free list
|
|
111
|
-
for (;;) {
|
|
112
|
-
AtomicSet(current->Next, AtomicGet(FreePtr));
|
|
113
|
-
if (AtomicCas(&FreePtr, current, current->Next))
|
|
114
|
-
break;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
return true;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
TryToFreeMemory();
|
|
121
|
-
AtomicAdd(DequeueCount, -1);
|
|
122
|
-
return false;
|
|
123
|
-
}
|
|
124
|
-
// add all elements to *res
|
|
125
|
-
// elements are returned in order of dequeue (top to bottom; see example in unittest)
|
|
126
|
-
template <typename TCollection>
|
|
127
|
-
void DequeueAll(TCollection* res) {
|
|
128
|
-
AtomicAdd(DequeueCount, 1);
|
|
129
|
-
for (TNode* current = AtomicGet(Head); current; current = AtomicGet(Head)) {
|
|
130
|
-
if (AtomicCas(&Head, (TNode*)nullptr, current)) {
|
|
131
|
-
for (TNode* x = current; x;) {
|
|
132
|
-
res->push_back(std::move(x->Value));
|
|
133
|
-
x = x->Next;
|
|
134
|
-
}
|
|
135
|
-
// EraseList(current); // ABA problem
|
|
136
|
-
// even more complex node deletion
|
|
137
|
-
TryToFreeMemory();
|
|
138
|
-
if (AtomicAdd(DequeueCount, -1) == 0) {
|
|
139
|
-
// no other Dequeue()s, can safely reclaim memory
|
|
140
|
-
EraseList(current);
|
|
141
|
-
} else {
|
|
142
|
-
// Dequeue()s in progress, add nodes list to free list
|
|
143
|
-
TNode* currentLast = current;
|
|
144
|
-
while (currentLast->Next) {
|
|
145
|
-
currentLast = currentLast->Next;
|
|
146
|
-
}
|
|
147
|
-
for (;;) {
|
|
148
|
-
AtomicSet(currentLast->Next, AtomicGet(FreePtr));
|
|
149
|
-
if (AtomicCas(&FreePtr, current, currentLast->Next))
|
|
150
|
-
break;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
TryToFreeMemory();
|
|
157
|
-
AtomicAdd(DequeueCount, -1);
|
|
158
|
-
}
|
|
159
|
-
bool DequeueSingleConsumer(T* res) {
|
|
160
|
-
for (TNode* current = AtomicGet(Head); current; current = AtomicGet(Head)) {
|
|
161
|
-
if (AtomicCas(&Head, current->Next, current)) {
|
|
162
|
-
*res = std::move(current->Value);
|
|
163
|
-
delete current; // with single consumer thread ABA does not happen
|
|
164
|
-
return true;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
return false;
|
|
168
|
-
}
|
|
169
|
-
// add all elements to *res
|
|
170
|
-
// elements are returned in order of dequeue (top to bottom; see example in unittest)
|
|
171
|
-
template <typename TCollection>
|
|
172
|
-
void DequeueAllSingleConsumer(TCollection* res) {
|
|
173
|
-
for (TNode* current = AtomicGet(Head); current; current = AtomicGet(Head)) {
|
|
174
|
-
if (AtomicCas(&Head, (TNode*)nullptr, current)) {
|
|
175
|
-
for (TNode* x = current; x;) {
|
|
176
|
-
res->push_back(std::move(x->Value));
|
|
177
|
-
x = x->Next;
|
|
178
|
-
}
|
|
179
|
-
EraseList(current); // with single consumer thread ABA does not happen
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
bool IsEmpty() {
|
|
185
|
-
AtomicAdd(DequeueCount, 0); // mem barrier
|
|
186
|
-
return AtomicGet(Head) == nullptr; // without lock, so result is approximate
|
|
187
|
-
}
|
|
188
|
-
};
|