This repository has been archived by the owner on Jun 22, 2023. It is now read-only.
forked from scylladb/seastar
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
When using print() to debug on smp, it is very annoying to get interleaved output. Fix by wrapping stdout with a fake stream that has a line buffer for each thread.
- Loading branch information
Showing
4 changed files
with
92 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* | ||
* Copyright (C) 2015 Cloudius Systems, Ltd. | ||
*/ | ||
|
||
|
||
#include "stdio.hh" | ||
#include <memory> | ||
#include <pthread.h> | ||
#include <mutex> | ||
#include <unordered_map> | ||
#include <boost/thread/tss.hpp> | ||
#include <vector> | ||
#include <algorithm> | ||
|
||
class spinlock { | ||
pthread_spinlock_t _l; | ||
public: | ||
spinlock() { pthread_spin_init(&_l, PTHREAD_PROCESS_PRIVATE); } | ||
~spinlock() { pthread_spin_destroy(&_l); } | ||
void lock() { pthread_spin_lock(&_l); } | ||
void unlock() { pthread_spin_unlock(&_l); } | ||
}; | ||
|
||
class smp_file { | ||
FILE* _out; | ||
spinlock _lock; | ||
boost::thread_specific_ptr<std::vector<char>> _buffer; | ||
static constexpr size_t max = 2000; | ||
public: | ||
smp_file(FILE* out) : _out(out) {} | ||
ssize_t write(const char* buffer, size_t size) { | ||
auto& b = *_buffer; | ||
b.insert(b.end(), buffer, buffer + size); | ||
size_t now = 0; | ||
if (b.size() >= max) { | ||
now = b.size(); | ||
} else { | ||
auto lf = std::find(b.rbegin(), b.rend(), '\n'); | ||
if (lf != b.rend()) { | ||
auto remain = lf - b.rbegin(); | ||
now = b.size() - remain; | ||
} | ||
} | ||
if (now) { | ||
auto ret = fwrite(b.data(), 1, now, _out); | ||
b.erase(b.begin(), b.begin() + now); | ||
return ret; | ||
} else { | ||
return 0; | ||
} | ||
} | ||
}; | ||
|
||
static smp_file* to_smp_file(void* cookie) { | ||
return static_cast<smp_file*>(cookie); | ||
} | ||
|
||
FILE* | ||
smp_synchronize_lines(FILE* out) { | ||
auto p = std::make_unique<smp_file>(out); | ||
cookie_io_functions_t vtable = {}; | ||
vtable.write = [] (void* ck, const char* b, size_t s) { return to_smp_file(ck)->write(b, s); }; | ||
vtable.close = [] (void* ck) { delete to_smp_file(ck); return 0; }; | ||
auto ret = fopencookie(p.get(), "w", vtable); | ||
if (!ret) { | ||
return ret; | ||
} | ||
// disable buffering so that writes to ret don't get mixed | ||
// up but are sent to smp_file immediately instead. | ||
setvbuf(ret, nullptr, _IONBF, 0); | ||
p.release(); | ||
return ret; | ||
} | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
/* | ||
* Copyright (C) 2015 Cloudius Systems, Ltd. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <stdio.h> | ||
|
||
// Returns a FILE* that writes all its output to @out, but attempts | ||
// not to mix lines if multiple threads write to it simultaenously. | ||
FILE* smp_synchronize_lines(FILE* out); | ||
|