Skip to content

Commit fe01da0

Browse files
committed
Make threaded version work again
1 parent d43a4e9 commit fe01da0

File tree

3 files changed

+17
-24
lines changed

3 files changed

+17
-24
lines changed

include/simdjson/dom/document_stream.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ class document_stream {
120120
inline size_t next_batch_start() const noexcept;
121121

122122
/** Pass the next batch through stage 1 with the given parser. */
123-
inline void run_stage1(dom::parser &p, size_t batch_start) noexcept;
123+
inline error_code run_stage1(dom::parser &p, size_t batch_start) noexcept;
124124

125125
dom::parser &parser;
126126
const uint8_t *buf;
@@ -131,20 +131,19 @@ class document_stream {
131131
error_code error;
132132

133133
#ifdef SIMDJSON_THREADS_ENABLED
134-
/**
135-
* Start a thread to run stage 1 on the next batch.
136-
*/
134+
inline void load_from_stage1_thread() noexcept;
135+
136+
/** Start a thread to run stage 1 on the next batch. */
137137
inline void start_stage1_thread() noexcept;
138138

139-
/**
140-
* Wait for the stage 1 thread to finish and capture the results.
141-
*/
139+
/** Wait for the stage 1 thread to finish and capture the results. */
142140
inline void finish_stage1_thread() noexcept;
143141

144142
/** The error returned from the stage 1 thread. */
145143
error_code stage1_thread_error{UNINITIALIZED};
146144
/** The thread used to run stage 1 against the next batch in the background. */
147145
std::thread stage1_thread{};
146+
148147
/**
149148
* The parser used to run stage 1 in the background. Will be swapped
150149
* with the regular parser when finished.

include/simdjson/inline/document_stream.h

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,13 @@ inline void document_stream::start() noexcept {
7272

7373
// Always run the first stage 1 parse immediately
7474
batch_start = 0;
75-
run_stage1(parser, batch_start);
75+
error = run_stage1(parser, batch_start);
7676
if (error) { return; }
7777

7878
#ifdef SIMDJSON_THREADS_ENABLED
7979
if (next_batch_start() < len) {
8080
// Kick off the first thread if needed
81-
error = thread_parser.ensure_capacity(batch_size);
81+
error = stage1_thread_parser.ensure_capacity(batch_size);
8282
if (error) { return; }
8383
start_stage1_thread();
8484
if (error) { return; }
@@ -102,7 +102,7 @@ inline void document_stream::next() noexcept {
102102
#ifdef SIMDJSON_THREADS_ENABLED
103103
load_from_stage1_thread();
104104
#else
105-
run_stage1(parser, batch_start);
105+
error = run_stage1(parser, batch_start);
106106
#endif
107107
if (error) { continue; } // If the error was EMPTY, we may want to load another batch.
108108

@@ -115,13 +115,13 @@ inline size_t document_stream::next_batch_start() const noexcept {
115115
return batch_start + parser.implementation->structural_indexes[parser.implementation->n_structural_indexes];
116116
}
117117

118-
inline void document_stream::run_stage1(dom::parser &p, size_t _batch_start) noexcept {
118+
inline error_code document_stream::run_stage1(dom::parser &p, size_t _batch_start) noexcept {
119119
// If this is the final batch, pass partial = false
120120
size_t remaining = len - _batch_start;
121121
if (remaining <= batch_size) {
122-
error = p.implementation->stage1(&buf[_batch_start], remaining, false);
122+
return p.implementation->stage1(&buf[_batch_start], remaining, false);
123123
} else {
124-
error = p.implementation->stage1(&buf[_batch_start], batch_size, true);
124+
return p.implementation->stage1(&buf[_batch_start], batch_size, true);
125125
}
126126
}
127127

@@ -132,10 +132,9 @@ inline void document_stream::load_from_stage1_thread() noexcept {
132132

133133
// Swap to the parser that was loaded up in the thread. Make sure the parser has
134134
// enough memory to swap to, as well.
135-
error = parser.ensure_capacity(batch_size);
136-
if (error) { return error; }
137135
std::swap(parser, stage1_thread_parser);
138-
if (stage1_thread_error) { return stage1_thread_error; }
136+
error = stage1_thread_error;
137+
if (error) { return; }
139138

140139
// If there's anything left, start the stage 1 thread!
141140
if (next_batch_start() < len) {
@@ -149,11 +148,9 @@ inline void document_stream::start_stage1_thread() noexcept {
149148
// there is only one thread that may write to this value
150149
// TODO this is NOT exception-safe.
151150
this->stage1_thread_error = UNINITIALIZED; // In case something goes wrong, make sure it's an error
152-
stage1_thread = std::thread([this] {
153-
this->stage1_thread_error = this->thread_parser.ensure_capacity(this->batch_size);
154-
if (!this->stage1_thread_error) {
155-
this->stage1_thread_error = run_stage1(this->stage1_thread_parser, this->next_batch_start());
156-
}
151+
size_t _next_batch_start = this->next_batch_start();
152+
stage1_thread = std::thread([this, _next_batch_start] {
153+
this->stage1_thread_error = run_stage1(this->stage1_thread_parser, _next_batch_start);
157154
});
158155
}
159156

tests/basictests.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -561,9 +561,6 @@ namespace parse_api_tests {
561561
memcpy(&empty_batches_ndjson[BATCH_SIZE*3+2], "1", 1);
562562
memcpy(&empty_batches_ndjson[BATCH_SIZE*10+4], "2", 1);
563563
memcpy(&empty_batches_ndjson[BATCH_SIZE*11+6], "3", 1);
564-
for (int i=0; i<16; i++) {
565-
printf("| %.*s |", BATCH_SIZE, &empty_batches_ndjson[BATCH_SIZE*i]);
566-
}
567564
for (auto [doc, error] : parser.parse_many(empty_batches_ndjson, BATCH_SIZE*16)) {
568565
if (error) { cerr << "Error in parse_many: " << error << endl; return false; }
569566
count++;

0 commit comments

Comments
 (0)