-PEDANTRY = -Weverything -pedantic-errors -Werror -Wno-c++98-compat \
- -Wno-c++98-compat-pedantic -Wno-padded -Wno-missing-prototypes \
- -Wmissing-declarations -Wno-weak-vtables -Wno-global-constructors \
- -Wno-exit-time-destructors -pedantic -Wall -Wextra -Weffc++
-OPTFLAGS = -O3 -fno-omit-frame-pointer #-fsanitize=address ,thread,undefined -fsanitize-memory-track-origins
-STDLIB = -stdlib=libc++
-#STDLIB =
-CXX = clang++-mp-3.4
-#CXX = g++-mp-4.8
+USE_CLANG = 1
+
+PEDANTRY =
+STDLIB =
+OPTFLAGS = -O3 #-fno-omit-frame-pointer -fsanitize=address ,thread,undefined -fsanitize-memory-track-origins
CXXFLAGS = -std=c++11 -ggdb3 -MMD -I. $(STDLIB) $(PEDANTRY) $(OPTFLAGS)
LDFLAGS = -std=c++11 $(STDLIB) $(OPTFLAGS)
+
+ifeq "$(USE_CLANG)" "1"
+
+PEDANTRY += \
+ -Weverything -pedantic-errors -Werror -Wno-c++98-compat \
+ -Wno-c++98-compat-pedantic -Wno-padded -Wno-global-constructors \
+ -Wno-exit-time-destructors -pedantic -Wall -Wextra -Weffc++
+STDLIB += -stdlib=libc++
+CXX = clang++-mp-3.4
+
+else
+
+PEDANTRY += -pedantic -Wall -Wextra -fno-default-inline -Werror
+STDLIB += -pthread
+CXX = g++-mp-4.8
+
+endif
+
CC := $(CXX)
EXTRA_TARGETS = signatures
// all views, the other nodes can bring this re-joined node up to
// date.
+config_view_change::~config_view_change() {}
+
config::config(const string & _first, const string & _me, config_view_change *_vc)
: my_view_id(0), first(_first), me(_me), vc(_vc),
paxos(this, me == _first, me, me)
class config_view_change {
public:
virtual void commit_change(unsigned view_id) = 0;
- virtual ~config_view_change() {}
+ virtual ~config_view_change();
};
class config : public paxos_change {
-// lock protocol
-
#ifndef lock_protocol_h
#define lock_protocol_h
REMOTE_PROCEDURE(1, acquire, (int &, lockid_t, callback_t, xid_t));
REMOTE_PROCEDURE(2, release, (int &, lockid_t, callback_t, xid_t));
REMOTE_PROCEDURE(3, stat, (int &, lockid_t, callback_t));
-};
+}
namespace rlock_protocol {
using lockid_t = lock_protocol::lockid_t;
REMOTE_PROCEDURE_BASE(0x8000);
REMOTE_PROCEDURE(1, revoke, (int &, lockid_t, xid_t));
REMOTE_PROCEDURE(2, retry, (int &, lockid_t, xid_t));
-};
+}
#endif
static int ct[256];
static mutex count_mutex;
-void check_grant(lock_protocol::lockid_t lid) {
+static void check_grant(lock_protocol::lockid_t lid) {
lock ml(count_mutex);
int x = lid[0] & 0x0f;
if (ct[x] != 0) {
ct[x] += 1;
}
-void check_release(lock_protocol::lockid_t lid) {
+static void check_release(lock_protocol::lockid_t lid) {
lock ml(count_mutex);
int x = lid[0] & 0x0f;
if (ct[x] != 1) {
ct[x] -= 1;
}
-void test1(void) {
+static void test1(void) {
LOG_NONMEMBER("acquire a release a acquire a release a");
lc[0]->acquire(a);
check_grant(a);
check_release(a);
}
-void test2(int i) {
+static void test2(int i) {
LOG_NONMEMBER("test2: client " << i << " acquire a release a");
lc[i]->acquire(a);
LOG_NONMEMBER("test2: client " << i << " acquire done");
LOG_NONMEMBER("test2: client " << i << " release done");
}
-void test3(int i) {
+static void test3(int i) {
LOG_NONMEMBER("test3: client " << i << " acquire a release a concurrent");
for (int j = 0; j < 10; j++) {
lc[i]->acquire(a);
}
}
-void test4(int i) {
+static void test4(int i) {
LOG_NONMEMBER("test4: thread " << i << " acquire a release a concurrent; same clnt");
for (int j = 0; j < 10; j++) {
lc[0]->acquire(a);
}
}
-void test5(int i) {
+static void test5(int i) {
LOG_NONMEMBER("test5: client " << i << " acquire a release a concurrent; same and diff clnt");
for (int j = 0; j < 10; j++) {
if (i < 5) lc[0]->acquire(a);
#include "paxos.h"
#include "handle.h"
+paxos_change::~paxos_change() {}
+
bool isamember(const node_t & m, const nodes_t & nodes) {
return find(nodes.begin(), nodes.end(), m) != nodes.end();
}
class paxos_change {
public:
virtual void paxos_commit(unsigned instance, const value_t & v) = 0;
- virtual ~paxos_change() {}
+ virtual ~paxos_change();
};
extern bool isamember(const node_t & m, const nodes_t & nodes);
REMOTE_PROCEDURE(2, acceptreq, (bool &, node_t, unsigned, prop_t, value_t));
REMOTE_PROCEDURE(3, decidereq, (int &, node_t, unsigned, value_t));
REMOTE_PROCEDURE(4, heartbeat, (int &, string, unsigned));
-};
+}
MARSHALLABLE_STRUCT(paxos_protocol::prepareres)
#include <unistd.h>
#include "marshall.h"
+connection_delegate::~connection_delegate() {}
+
connection::connection(connection_delegate * delegate, socket_t && f1, int l1)
: fd(move(f1)), delegate_(delegate), lossy_(l1)
{
tcp_.setsockopt(SOL_SOCKET, SO_RCVTIMEO, timeval{0, 50000});
tcp_.setsockopt(SOL_SOCKET, SO_SNDTIMEO, timeval{0, 50000});
- sockaddr_in sin{}; // zero initialize
+ sockaddr_in sin = sockaddr_in(); // zero initialize
sin.sin_family = AF_INET;
sin.sin_port = hton(port);
int s1 = accept(tcp_, (sockaddr *)&sin, &slen);
if (s1 < 0) {
perror("connection_listener::accept_conn error");
- throw thread_exit_exception();
+ throw runtime_error("connection listener failure");
}
IF_LEVEL(2) LOG("accept_loop got connection fd=" << s1 << " " << inet_ntoa(sin.sin_addr) << ":" << ntoh(sin.sin_port));
constexpr size_t size_t_max = numeric_limits<size_t>::max();
-class thread_exit_exception : exception {};
-
class connection;
class connection_delegate {
public:
virtual bool got_pdu(const shared_ptr<connection> & c, const string & b) = 0;
- virtual ~connection_delegate() {}
+ virtual ~connection_delegate();
};
class connection : private aio_callback, public enable_shared_from_this<connection> {
// One for function pointers...
template <class F, class R, class RV, class args_type, size_t... Indices>
-typename enable_if<!is_member_function_pointer<F>::value, RV>::type
+typename enable_if<!is_member_function_pointer<F>::value, RV>::type inline
invoke(RV, F f, void *, R & r, args_type & t, tuple_indices<Indices...>) {
return f(r, move(get<Indices>(t))...);
}
// And one for pointers to member functions...
template <class F, class C, class RV, class R, class args_type, size_t... Indices>
-typename enable_if<is_member_function_pointer<F>::value, RV>::type
+typename enable_if<is_member_function_pointer<F>::value, RV>::type inline
invoke(RV, F f, C *c, R & r, args_type & t, tuple_indices<Indices...>) {
return (c->*f)(r, move(get<Indices>(t))...);
}
#include <sys/epoll.h>
#endif
+aio_callback::~aio_callback() {}
+
poll_mgr poll_mgr::shared_mgr;
class wait_manager {
virtual void watch_fd(int fd, poll_flag flag) = 0;
virtual bool unwatch_fd(int fd, poll_flag flag) = 0;
virtual void wait_ready(vector<int> & readable, vector<int> & writable) = 0;
- virtual ~wait_manager() noexcept {}
+ virtual ~wait_manager() noexcept;
};
+wait_manager::~wait_manager() noexcept {}
+
class SelectAIO : public wait_manager {
public :
SelectAIO();
public:
virtual void read_cb(int fd) = 0;
virtual void write_cb(int fd) = 0;
- virtual ~aio_callback() {}
+ virtual ~aio_callback();
};
class poll_mgr {
IF_LEVEL(2) LOG("bind " << inet_ntoa(dst_.sin_addr) << " failed " << ret);
}
return ret;
-};
+}
// Cancel all outstanding calls
void rpcc::cancel(void) {
port = hostandport.substr(colon+1);
}
- sockaddr_in dst{}; // zero initialize
+ sockaddr_in dst = sockaddr_in(); // zero initialize
dst.sin_family = AF_INET;
struct in_addr a{inet_addr(host.c_str())};
const size_t DEFAULT_RPC_SZ = 1024; // size of initial buffer allocation
const size_t MAX_PDU = 10<<20; // maximum PDF is 10M
-#define REMOTE_PROCEDURE_BASE(_base_) static constexpr rpc_protocol::proc_id_t base = _base_;
-#define REMOTE_PROCEDURE(_offset_, _name_, _args_) static constexpr rpc_protocol::proc_t<status _args_> _name_{base + _offset_};
+#define REMOTE_PROCEDURE_BASE(_base_) static constexpr rpc_protocol::proc_id_t base = _base_
+#define REMOTE_PROCEDURE(_offset_, _name_, _args_) static constexpr rpc_protocol::proc_t<status _args_> _name_{base + _offset_}
REMOTE_PROCEDURE_BASE(0);
REMOTE_PROCEDURE(1, bind, (nonce_t &)); // handler number reserved for bind
-};
+}
ENDIAN_SWAPPABLE(rpc_protocol::request_header)
ENDIAN_SWAPPABLE(rpc_protocol::reply_header)
REMOTE_PROCEDURE(23, fast, (int &, int));
REMOTE_PROCEDURE(24, slow, (int &, int));
REMOTE_PROCEDURE(25, bigrep, (string &, size_t));
-};
+}
// a handler. a and b are arguments, r is the result.
// there can be multiple arguments but only one result.
static srv service;
-void startserver() {
+static void startserver() {
server = new rpcs(port);
server->reg(srv_protocol::_22, &srv::handle_22, &service);
server->reg(srv_protocol::fast, &srv::handle_fast, &service);
server->start();
}
-void testmarshall() {
+static void testmarshall() {
marshall m;
rpc_protocol::request_header rh{1,2,3,4,5};
m.pack_header(rh);
unsigned long long l = 1223344455L;
size_t sz = 101010101;
string s = "hallo....";
+ string bin("\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x7f\xe5", 12);
m << i;
m << l;
m << s;
m << sz;
+ m << bin;
string b = m;
- VERIFY(b.size() == rpc_protocol::RPC_HEADER_SZ+sizeof(i)+sizeof(l)+s.size()+sizeof(int)+sizeof(uint32_t));
+ VERIFY(b.size() == rpc_protocol::RPC_HEADER_SZ+sizeof(i)+sizeof(l)+sizeof(uint32_t)+s.size()+sizeof(uint32_t)+sizeof(uint32_t)+bin.size());
unmarshall un(b, true);
rpc_protocol::request_header rh1;
int i1;
unsigned long long l1;
string s1;
+ string bin1;
size_t sz1;
un >> i1;
un >> l1;
un >> s1;
un >> sz1;
+ un >> bin1;
VERIFY(un.okdone());
- VERIFY(i1==i && l1==l && s1==s && sz1==sz);
+ VERIFY(i1==i && l1==l && s1==s && sz1==sz && bin1==bin);
}
-void client1(size_t cl) {
+static void client1(size_t cl) {
// test concurrency.
size_t which_cl = cl % NUM_CL;
}
}
-void client2(size_t cl) {
+static void client2(size_t cl) {
size_t which_cl = cl % NUM_CL;
time_t t1;
}
}
-void client3(void *xx) {
+static void client3(void *xx) {
rpcc *c = (rpcc *) xx;
for(int i = 0; i < 4; i++){
}
}
-void simple_tests(rpcc *c) {
+static void simple_tests(rpcc *c) {
cout << "simple_tests" << endl;
// an RPC call to procedure #22.
// rpcc::call() looks at the argument types to decide how
cout << "simple_tests OK" << endl;
}
-void concurrent_test(size_t nt) {
+static void concurrent_test(size_t nt) {
// create threads that make lots of calls in parallel,
// to test thread synchronization for concurrent calls
// and dispatches.
cout << " OK" << endl;
}
-void lossy_test() {
+static void lossy_test() {
cout << "start lossy_test ...";
VERIFY(setenv("RPC_LOSSY", "5", 1) == 0);
VERIFY(setenv("RPC_LOSSY", "0", 1) == 0);
}
-void failure_test() {
+static void failure_test() {
rpcc *client1;
rpcc *client = clients[0];
#include "rsm_client.h"
#include <unistd.h>
+rsm_state_transfer::~rsm_state_transfer() {}
+
rsm::rsm(const string & _first, const string & _me) : primary(_first)
{
cfg = unique_ptr<config>(new config(_first, _me, this));
partition1(rsm_mutex_lock);
}
}
+ LOG(setfill('0') << setw(2) << hex;
+ for (size_t i=0; i<req.size(); i++)
+ cerr << (unsigned int)(unsigned char)req[i];
+ cerr);
execute(procno, req, r);
- for (size_t i=0; i<r.size(); i++) {
- LOG(hex << setfill('0') << setw(2) << (unsigned int)(unsigned char)r[i]);
- }
+ LOG(setfill('0') << setw(2) << hex;
+ for (size_t i=0; i<r.size(); i++)
+ cerr << (unsigned int)(unsigned char)r[i];
+ cerr);
last_myvs = vs;
return rsm_client_protocol::OK;
}
public:
virtual string marshal_state() = 0;
virtual void unmarshal_state(const string &) = 0;
- virtual ~rsm_state_transfer() {}
+ virtual ~rsm_state_transfer();
};
class rsm : public config_view_change {
rsm_client(string dst);
template<class P, class R, class ...Args>
- int call(rpc_protocol::proc_t<P> proc, R & r, const Args & ...a1) {
+ inline int call(rpc_protocol::proc_t<P> proc, R & r, const Args & ...a1) {
static_assert(is_valid_call<P, R, Args...>::value, "RSM method invoked with incorrect argument types");
return call_m(proc.id, r, marshall(a1...));
}
REMOTE_PROCEDURE_BASE(0x9000);
REMOTE_PROCEDURE(1, invoke, (string &, rpc_protocol::proc_id_t, string));
REMOTE_PROCEDURE(2, members, (vector<string> &, int));
-};
+}
struct viewstamp {
unsigned int vid;
REMOTE_PROCEDURE(2, transferreq, (transferres &, string, viewstamp, unsigned));
REMOTE_PROCEDURE(3, transferdonereq, (int &, string, unsigned));
REMOTE_PROCEDURE(4, joinreq, (string &, string, viewstamp));
-};
+}
MARSHALLABLE_STRUCT(rsm_protocol::transferres)
REMOTE_PROCEDURE_BASE(0x12000);
REMOTE_PROCEDURE(1, net_repair, (status &, int));
REMOTE_PROCEDURE(2, breakpoint, (status &, int));
-};
+}
#endif
extern int next_instance_num;
extern char log_thread_prefix;
-namespace std {
- // Sticking this in std:: makes it possible for ostream_iterator to use it.
- template <class A, class B>
- ostream & operator<<(ostream & o, const pair<A,B> & d) {
- return o << "<" << d.first << "," << d.second << ">";
- }
-}
-
-template <class A>
-typename enable_if<is_const_iterable<A>::value && !is_same<A,string>::value, ostream>::type &
-operator<<(ostream & o, const A & a) {
- return o << "[" << implode(a, ", ") << "]";
-}
-
#define LOG_PREFIX { \
auto _thread_ = this_thread::get_id(); \
int _tid_ = thread_name_map[_thread_]; \
using std::mutex;
using lock = std::unique_lock<std::mutex>;
+#include <stdexcept>
+using std::runtime_error;
+
#include <sstream>
using std::ostringstream;
using std::istringstream;
// string manipulation
+template <class A, class B>
+ostream & operator<<(ostream & o, const pair<A,B> & d) {
+ return o << "<" << d.first << "," << d.second << ">";
+}
+
template <class C>
inline typename enable_if<is_const_iterable<C>::value, string>::type
implode(const C & v, string delim=" ") {
return out;
}
+template <class A>
+typename enable_if<is_const_iterable<A>::value && !is_same<A,string>::value, ostream>::type &
+operator<<(ostream & o, const A & a) {
+ return o << "[" << implode(a, ", ") << "]";
+}
+
#include "verify.h"
#include "threaded_log.h"