sporadic latencies with SP_receive

Johannes Wienke <[email protected]>
Newsgroups gmane.network.spread.user
Message-ID <[email protected]>
Dear all,

we encountered some latency issues in our applications using spread.
Today we tried to isolate the problem and came up with a test program
that demonstrates the behavior.

Generally, the observation is that in a threaded setup, using local
communication, and a small sleep between calls to SP_receive, these
receive calls sometimes take up to 100 ms, e.g. generating this log:

receive took 55 us
receive took 68 us
receive took 97071 us
receive took 54 us
receive took 67 us
receive took 97060 us
receive took 54 us
receive took 68 us
receive took 97086 us
receive took 56 us
receive took 69 us
receive took 97091 us
receive took 56 us
receive took 67 us
receive took 97071 us

The attached program exactly produces this output. Please note that this
only happens if the sleep call is present in line 108.

We have also verified that this is not related to the architecture we
are running on (Linux 32 and 64 bit), nevertheless we got a stack
corruption on 32 bit in the sender thread with a privateGroup array only
MAX_PRIVATE_NAME characters long. Thus the increased size. Is this also
a known problem?

We would be happy to get some insights or fixes in how to prevent this
issue. In a real application the sleep is usually not required to
trigger the problem as the receiving thread is still doing other things
in its loop.

Regards,
Johannes

_______________________________________________
Spread-users mailing list
[email protected]
http://lists.spread.org/mailman/listinfo/spread-users
spreadtest.cpp (text/x-c++src, 3 KB)
//============================================================================
// Name        : spreadtest.cpp
// Author      : Johannes Wienke
// Version     :
// Copyright   : 2011, CoR-Lab, Bielefeld University
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <algorithm>
#include <iostream>
#include <string>

#include <assert.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>

#include <boost/cstdint.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>

#include <sp.h>

using namespace std;

char randAlnumChar() {
	char c;
	do {
		c = (char) (rand() % ('z' - '0' + 1) + '0');
	} while (!std::isalnum(c));
	return c;
}

std::string randAlnumStr(const std::string::size_type &length) {
	std::string s;
	s.reserve(length);
	generate_n(std::back_inserter(s), length, randAlnumChar);
	return s;
}

void currentTimeMicros(boost::uint64_t &result) {

	timeval tv;
	gettimeofday(&tv, NULL);

	// (second-value in microseconds) + (microsecond value)
	result = (((boost::uint64_t) tv.tv_sec) * 1000000ull) + (tv.tv_usec);

}

unsigned int numMessages = 1000;
unsigned int dataLength = 100000;

void sender() {

	char privateGroup[MAX_PRIVATE_NAME + 1000];
	mailbox sendMbox;
	int connected = SP_connect("4803", 0, 0, false, &sendMbox, privateGroup);
	assert(connected == ACCEPT_SESSION);

	string groupName = "foo";

	// first send some messages
	string data = randAlnumStr(dataLength);
	for (unsigned int i = 0; i < numMessages; ++i) {
		int sent = SP_multicast(sendMbox, RELIABLE_MESS, groupName.c_str(), 0,
				strlen(data.c_str()) + 1, data.c_str());
		assert(sent >= 0);
	}

	int disconnected = SP_disconnect(sendMbox);
	assert(disconnected == 0);
	cout << "##### disconnected!" << endl;

}

int main() {

	boost::thread senderThread(&sender);

	char privateGroup[MAX_PRIVATE_NAME];
	mailbox receiveMbox;
	int connected = SP_connect("4803", 0, 0, false, &receiveMbox, privateGroup);
	assert(connected == ACCEPT_SESSION);

	string groupName = "foo";
	SP_join(receiveMbox, groupName.c_str());

	// then receive them
	service service;
	char sender[MAX_GROUP_NAME];
	int maxGroups = 10;
	int numGroups = 0;
	char groups[maxGroups][MAX_GROUP_NAME];
	short int messageType;
	int endian;
	char message[dataLength + 10];
	boost::uint64_t before;
	boost::uint64_t after;
	for (unsigned int i = 0; i < numMessages; ++i) {
		currentTimeMicros(before);
		int size = SP_receive(receiveMbox, &service, sender, maxGroups,
				&numGroups, groups, &messageType, &endian, dataLength + 10,
				message);
		currentTimeMicros(after);
		cout << "receive took " << (after - before) << " us" << endl;
		assert(size >= 0);
		boost::this_thread::sleep(boost::posix_time::milliseconds(1));
	}

	cout << "received messages" << endl;

	// leave group, disconnect mailboxes
	int left = SP_leave(receiveMbox, groupName.c_str());
	assert(left == 0);
	int disconnected = SP_disconnect(receiveMbox);
	assert(disconnected == 0);

	senderThread.join();

	return 0;

}
signature.asc (application/pgp-signature, 262 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk4tV8gACgkQBFcR5UV/ccK1kACeIm3zyTkVHjWnKvOhz3wKIK9+
BDIAnREpN0eJhiJG/6H3sfxREtthp+38
=6zal
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.