Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support shenango threads in folly #5

Open
wants to merge 9 commits into
base: feature/add-folly
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions apps/test/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Makefile for simple app
ROOT_PATH=../..
include $(ROOT_PATH)/build/shared.mk

test_atomic_src = test_atomic.cc
test_atomic_obj = $(test_atomic_src:.cc=.o)

test_memory_order_src = test_memory_order.cc
test_memory_order_obj = $(test_memory_order_src:.cc=.o)

librt_libs = $(ROOT_PATH)/bindings/cc/librt++.a
INC += -I$(ROOT_PATH)/bindings/cc

RUNTIME_LIBS := $(RUNTIME_LIBS) -lnuma

all: test_atomic test_memory_order

test_atomic: $(test_atomic_obj) $(librt_libs) $(RUNTIME_DEPS)
$(LDXX) -o $@ $(LDFLAGS) $(test_atomic_obj) \
$(librt_libs) $(RUNTIME_LIBS)

test_memory_order: $(test_memory_order_obj) $(librt_libs) $(RUNTIME_DEPS)
$(LDXX) -o $@ $(LDFLAGS) $(test_memory_order_obj) \
$(librt_libs) $(RUNTIME_LIBS)

src = $(test_atomic_src) $(test_memory_order_src)
obj = $(src:.cc=.o)
dep = $(obj:.o=.d)

ifneq ($(MAKECMDGOALS),clean)
-include $(dep)
endif

%.d: %.cc
@$(CXX) $(CXXFLAGS) $< -MM -MT $(@:.d=.o) >$@
%.o: %.cc
$(CXX) $(CXXFLAGS) -c $< -o $@

.PHONY: clean
clean:
rm -f $(obj) $(dep) test_atomic test_memory_order
64 changes: 64 additions & 0 deletions apps/test/test_atomic.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* test_atomic.cc - tests support of std lib atomics
*/

extern "C" {
#include <base/log.h>
}

#include "runtime.h"
#include "sync.h"
#include "thread.h"
#include "timer.h"

#include <atomic>
#include <iostream>

namespace {

int threads;

void MainHandler(void *arg) {
rt::WaitGroup wg(threads);
std::atomic<bool> ready(false);
std::atomic_flag winner = ATOMIC_FLAG_INIT;

for (int i = 0; i < threads; ++i) {
rt::Spawn([&, i]() {
while (!ready) {
rt::Yield();
}
rt::Delay(10000);
if (!winner.test_and_set()) {
log_info("thread #%d won!", i);
}
wg.Done();
});
}

ready = true;

wg.Wait();
log_info("test complete");
}

} // namespace

int main(int argc, char *argv[]) {
int ret;

if (argc != 3) {
std::cerr << "usage: [config_file] [#threads]" << std::endl;
return -EINVAL;
}

threads = std::stoi(argv[2], nullptr, 0);

ret = runtime_init(argv[1], MainHandler, NULL);
if (ret) {
printf("failed to start runtime\n");
return ret;
}

return 0;
}
95 changes: 95 additions & 0 deletions apps/test/test_memory_order.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* test_atomic.cc - tests support of std lib atomics
*/

extern "C" {
#include <base/log.h>
}

#include "runtime.h"
#include "sync.h"
#include "thread.h"
#include "timer.h"

#include <atomic>
#include <iostream>
#include <sstream>

namespace {

std::atomic<bool> x = ATOMIC_VAR_INIT(false);
std::atomic<bool> y = ATOMIC_VAR_INIT(false);
std::atomic<int> z = ATOMIC_VAR_INIT(0);

// Check rt::GetId() works.
void PrintId() {
// Check rt::SleepFor() works.
rt::SleepFor(std::chrono::milliseconds{5 * rt::kMilliseconds});
std::stringstream msg;
msg << "My ID is " << rt::GetId() << "\n";
std::cout << msg.str();
}

void WriteX() {
x.store(true, std::memory_order_seq_cst);
PrintId();
}

void WriteY() {
y.store(true, std::memory_order_seq_cst);
PrintId();
}

// z == 0 only if x=true, y=false
void ReadXThenY() {
while (!x.load(std::memory_order_seq_cst))
;
if (y.load(std::memory_order_seq_cst)) ++z;
PrintId();
}

// z == 0 only if x=false, y=true
void ReadYThenX() {
while (!y.load(std::memory_order_seq_cst))
;
if (x.load(std::memory_order_seq_cst)) ++z;
PrintId();
}

void MainHandler(void *arg) {
auto th1 = rt::Thread(WriteX);
auto th2 = rt::Thread(WriteY);
auto th3 = rt::Thread(ReadXThenY);
auto th4 = rt::Thread(ReadYThenX);

th1.Join();
th2.Join();
th3.Join();
th4.Join();

// Check hardware concurrency.
log_info("the hardware concurrency is %d", th1.HardwareConcurrency());

// assert(z.load() != 0);
// z==0 will never happen
log_info("the value of z is %d", z.load());
}

} // namespace

int main(int argc, char *argv[]) {
int ret;

if (argc != 2) {
std::cerr << "usage: [config_file]" << std::endl;
return -EINVAL;
}

ret = runtime_init(argv[1], MainHandler, NULL);
if (ret) {
printf("failed to start runtime\n");
return ret;
}

return 0;
}
2 changes: 1 addition & 1 deletion bindings/cc/net.cc
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include "net.h"

#include <algorithm>
#include <cstring>
#include <memory>
#include <algorithm>

namespace {

Expand Down
16 changes: 7 additions & 9 deletions bindings/cc/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@ class UdpConn : public NetConn {
}

// Gets the MTU-limited payload size.
static size_t PayloadSize() {
return static_cast<size_t>(udp_payload_size);
}
static size_t PayloadSize() { return static_cast<size_t>(udp_payload_size); }

// Gets the local UDP address.
netaddr LocalAddr() const { return udp_local_addr(c_); }
Expand Down Expand Up @@ -79,8 +77,8 @@ class UdpConn : public NetConn {
UdpConn(udpconn_t *c) : c_(c) {}

// disable move and copy.
UdpConn(const UdpConn&) = delete;
UdpConn& operator=(const UdpConn&) = delete;
UdpConn(const UdpConn &) = delete;
UdpConn &operator=(const UdpConn &) = delete;

udpconn_t *c_;
};
Expand Down Expand Up @@ -186,8 +184,8 @@ class TcpConn : public NetConn {
TcpConn(tcpconn_t *c) : c_(c) {}

// disable move and copy.
TcpConn(const TcpConn&) = delete;
TcpConn& operator=(const TcpConn&) = delete;
TcpConn(const TcpConn &) = delete;
TcpConn &operator=(const TcpConn &) = delete;

ssize_t WritevFullRaw(const iovec *iov, int iovcnt);
ssize_t ReadvFullRaw(const iovec *iov, int iovcnt);
Expand Down Expand Up @@ -223,8 +221,8 @@ class TcpQueue {
TcpQueue(tcpqueue_t *q) : q_(q) {}

// disable move and copy.
TcpQueue(const TcpQueue&) = delete;
TcpQueue& operator=(const TcpQueue&) = delete;
TcpQueue(const TcpQueue &) = delete;
TcpQueue &operator=(const TcpQueue &) = delete;

tcpqueue_t *q_;
};
Expand Down
40 changes: 20 additions & 20 deletions bindings/cc/sync.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,21 @@ extern "C" {
namespace rt {

// Force the compiler to access a memory location.
template<typename T>
template <typename T>
T volatile &access_once(T &t) {
static_assert(std::is_integral<T>::value, "Integral required.");
return static_cast<T volatile &>(t);
}

// Force the compiler to read a memory location.
template<typename T>
template <typename T>
T read_once(const T &p) {
static_assert(std::is_integral<T>::value, "Integral required.");
return static_cast<const T volatile &>(p);
}

// Force the compiler to write a memory location.
template<typename T>
template <typename T>
void write_once(T &p, const T &val) {
static_assert(std::is_integral<T>::value, "Integral required.");
static_cast<T volatile &>(p) = val;
Expand All @@ -41,12 +41,12 @@ class ThreadWaker {
~ThreadWaker() { assert(th_ == nullptr); }

// disable copy.
ThreadWaker(const ThreadWaker&) = delete;
ThreadWaker& operator=(const ThreadWaker&) = delete;
ThreadWaker(const ThreadWaker &) = delete;
ThreadWaker &operator=(const ThreadWaker &) = delete;

// allow move.
ThreadWaker(ThreadWaker &&w) : th_(w.th_) { w.th_ = nullptr; }
ThreadWaker& operator=(ThreadWaker &&w) {
ThreadWaker &operator=(ThreadWaker &&w) {
th_ = w.th_;
w.th_ = nullptr;
return *this;
Expand Down Expand Up @@ -79,8 +79,8 @@ class Preempt {
~Preempt() {}

// disable move and copy.
Preempt(const Preempt&) = delete;
Preempt& operator=(const Preempt&) = delete;
Preempt(const Preempt &) = delete;
Preempt &operator=(const Preempt &) = delete;

// Disables preemption.
void Lock() { preempt_disable(); }
Expand Down Expand Up @@ -146,8 +146,8 @@ class Spin {
private:
spinlock_t lock_;

Spin(const Spin&) = delete;
Spin& operator=(const Spin&) = delete;
Spin(const Spin &) = delete;
Spin &operator=(const Spin &) = delete;
};

// Pthread-like mutex support.
Expand All @@ -174,8 +174,8 @@ class Mutex {
private:
mutex_t mu_;

Mutex(const Mutex&) = delete;
Mutex& operator=(const Mutex&) = delete;
Mutex(const Mutex &) = delete;
Mutex &operator=(const Mutex &) = delete;
};

// RAII lock support (works with Spin, Preempt, and Mutex).
Expand All @@ -188,8 +188,8 @@ class ScopedLock {
private:
L *const lock_;

ScopedLock(const ScopedLock&) = delete;
ScopedLock& operator=(const ScopedLock&) = delete;
ScopedLock(const ScopedLock &) = delete;
ScopedLock &operator=(const ScopedLock &) = delete;
};

using SpinGuard = ScopedLock<Spin>;
Expand All @@ -206,8 +206,8 @@ class ScopedLockAndPark {
private:
L *const lock_;

ScopedLockAndPark(const ScopedLockAndPark&) = delete;
ScopedLockAndPark& operator=(const ScopedLockAndPark&) = delete;
ScopedLockAndPark(const ScopedLockAndPark &) = delete;
ScopedLockAndPark &operator=(const ScopedLockAndPark &) = delete;
};

using SpinGuardAndPark = ScopedLockAndPark<Spin>;
Expand All @@ -232,8 +232,8 @@ class CondVar {
private:
condvar_t cv_;

CondVar(const CondVar&) = delete;
CondVar& operator=(const CondVar&) = delete;
CondVar(const CondVar &) = delete;
CondVar &operator=(const CondVar &) = delete;
};

// Golang-like waitgroup support.
Expand Down Expand Up @@ -262,8 +262,8 @@ class WaitGroup {
private:
waitgroup_t wg_;

WaitGroup(const WaitGroup&) = delete;
WaitGroup& operator=(const WaitGroup&) = delete;
WaitGroup(const WaitGroup &) = delete;
WaitGroup &operator=(const WaitGroup &) = delete;
};

} // namespace rt
Loading