mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-12 21:53:28 +00:00
test/packet_stream: remove
The rationales behind this test are also covered by test/nic_loopback or they are outdated (e.g. blocking). Ref #1987
This commit is contained in:
parent
a9f4baf674
commit
7285f82f79
@ -1,339 +0,0 @@
|
||||
/*
|
||||
* \brief Test for the packet-streaming interface
|
||||
* \author Norman Feske
|
||||
* \date 2009-11-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <base/log.h>
|
||||
#include <base/env.h>
|
||||
#include <base/thread.h>
|
||||
#include <base/allocator_avl.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <os/packet_stream.h>
|
||||
|
||||
|
||||
/**
|
||||
* Specialized policy, using a small queue sizes
|
||||
*
|
||||
* Note that the ack queue size is smaller than the submit queue
|
||||
* size.
|
||||
*/
|
||||
typedef Genode::Packet_stream_policy<Genode::Packet_descriptor, 8, 4, char>
|
||||
Test_packet_stream_policy;
|
||||
|
||||
|
||||
enum { STACK_SIZE = 4096 };
|
||||
|
||||
|
||||
void Genode::Packet_stream_base::_debug_print_buffers()
|
||||
{
|
||||
Genode::log("_ds_local_base = ", _ds_local_base);
|
||||
Genode::log("_submit_queue_offset = ", Genode::Hex(_submit_queue_offset));
|
||||
Genode::log("_ack_queue_offset = ", Genode::Hex(_ack_queue_offset));
|
||||
Genode::log("_bulk_buffer_offset = ", Genode::Hex(_bulk_buffer_offset));
|
||||
Genode::log("_bulk_buffer_size = ", Genode::Hex(_bulk_buffer_size));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Thread generating packets
|
||||
*/
|
||||
class Source : private Genode::Thread_deprecated<STACK_SIZE>,
|
||||
private Genode::Allocator_avl,
|
||||
public Genode::Packet_stream_source<Test_packet_stream_policy>
|
||||
{
|
||||
private:
|
||||
|
||||
enum Operation { OP_NONE, OP_GENERATE, OP_ACKNOWLEDGE };
|
||||
|
||||
Operation _operation; /* current mode of operation */
|
||||
Genode::Lock _lock; /* lock used as barrier in the thread loop */
|
||||
unsigned _cnt; /* number of packets to produce */
|
||||
|
||||
void _generate_packets(unsigned cnt)
|
||||
{
|
||||
for (unsigned i = 0; i < cnt; i++) {
|
||||
try {
|
||||
enum { PACKET_SIZE = 1024 };
|
||||
Packet_descriptor packet = alloc_packet(PACKET_SIZE);
|
||||
|
||||
char *content = packet_content(packet);
|
||||
if (!content) {
|
||||
Genode::warning("source: invalid packet");
|
||||
}
|
||||
Genode::log("Source: allocated packet ("
|
||||
"offset=", Genode::Hex(packet.offset()), " "
|
||||
"size=", Genode::Hex(packet.size()), ")");
|
||||
|
||||
for (unsigned i = 0; i < packet.size(); i++)
|
||||
content[i] = i;
|
||||
|
||||
bool is_blocking = !ready_to_submit();
|
||||
if (is_blocking)
|
||||
Genode::log("Source: submit queue is full, going to block");
|
||||
|
||||
submit_packet(packet);
|
||||
|
||||
if (is_blocking)
|
||||
Genode::log("Source: returned from submit_packet function");
|
||||
|
||||
} catch (Packet_stream_source<>::Packet_alloc_failed) {
|
||||
Genode::error("Source: Packet allocation failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _acknowledge_packets(unsigned cnt)
|
||||
{
|
||||
for (unsigned i = 0; i < cnt; i++) {
|
||||
if (!ack_avail())
|
||||
Genode::log("Source: acknowledgement queue is empty, going to block");
|
||||
|
||||
Packet_descriptor packet = get_acked_packet();
|
||||
char *content = packet_content(packet);
|
||||
if (!content) {
|
||||
Genode::warning("source: invalid packet");
|
||||
|
||||
} else {
|
||||
|
||||
/* validate packet content */
|
||||
for (unsigned i = 0; i < packet.size(); i++) {
|
||||
if (content[i] != (char)i) {
|
||||
Genode::error("source: packet content is corrupted");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Genode::log("Source: release packet ("
|
||||
"offset=", Genode::Hex(packet.offset()), ", "
|
||||
"size=", packet.size(), ")");
|
||||
release_packet(packet);
|
||||
}
|
||||
}
|
||||
|
||||
void entry()
|
||||
{
|
||||
for (;;) {
|
||||
|
||||
/* wait for a new 'generate' or 'acknowledge' call */
|
||||
_lock.lock();
|
||||
|
||||
if (_operation == OP_GENERATE)
|
||||
_generate_packets(_cnt);
|
||||
|
||||
if (_operation == OP_ACKNOWLEDGE)
|
||||
_acknowledge_packets(_cnt);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Source(Genode::Dataspace_capability ds_cap)
|
||||
:
|
||||
/* init bulk buffer allocator, storing its meta data on the heap */
|
||||
Thread_deprecated("source"),
|
||||
Genode::Allocator_avl(Genode::env()->heap()),
|
||||
Packet_stream_source<Test_packet_stream_policy>(
|
||||
ds_cap, *Genode::env()->rm_session(), *this),
|
||||
_operation(OP_NONE),
|
||||
_lock(Genode::Lock::LOCKED),
|
||||
_cnt(0)
|
||||
{
|
||||
Genode::log("Source: packet stream buffers:");
|
||||
debug_print_buffers();
|
||||
start();
|
||||
}
|
||||
|
||||
void generate(unsigned cnt)
|
||||
{
|
||||
_cnt = cnt;
|
||||
_operation = OP_GENERATE;
|
||||
_lock.unlock();
|
||||
}
|
||||
|
||||
void acknowledge(unsigned cnt)
|
||||
{
|
||||
_cnt = cnt;
|
||||
_operation = OP_ACKNOWLEDGE;
|
||||
_lock.unlock();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Sink : private Genode::Thread_deprecated<STACK_SIZE>,
|
||||
public Genode::Packet_stream_sink<Test_packet_stream_policy>
|
||||
{
|
||||
private:
|
||||
|
||||
enum Operation { OP_NONE, OP_PROCESS };
|
||||
|
||||
Operation _operation; /* current mode of operation */
|
||||
Genode::Lock _lock; /* lock used as barrier in the thread loop */
|
||||
unsigned _cnt; /* number of packets to produce */
|
||||
|
||||
void _process_packets(unsigned cnt)
|
||||
{
|
||||
for (unsigned i = 0; i < cnt; i++) {
|
||||
|
||||
if (!packet_avail())
|
||||
Genode::log("Sink: no packet available, going to block");
|
||||
|
||||
Packet_descriptor packet = get_packet();
|
||||
|
||||
char *content = packet_content(packet);
|
||||
if (!content)
|
||||
Genode::warning("invalid packet");
|
||||
|
||||
Genode::log("Sink: got packet ("
|
||||
"offset=", Genode::Hex(packet.offset()), ", "
|
||||
"size=", packet.size(), ")");
|
||||
|
||||
if (!ready_to_ack())
|
||||
Genode::log("Sink: ack queue is full, going to block");
|
||||
|
||||
acknowledge_packet(packet);
|
||||
}
|
||||
}
|
||||
|
||||
void entry()
|
||||
{
|
||||
for (;;) {
|
||||
|
||||
/* wait for a new 'process' call */
|
||||
_lock.lock();
|
||||
|
||||
if (_operation == OP_PROCESS)
|
||||
_process_packets(_cnt);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Sink(Genode::Dataspace_capability ds_cap)
|
||||
:
|
||||
Thread_deprecated("sink"),
|
||||
Packet_stream_sink<Test_packet_stream_policy>(
|
||||
ds_cap, *Genode::env()->rm_session()),
|
||||
_operation(OP_NONE),
|
||||
_lock(Genode::Lock::LOCKED),
|
||||
_cnt(0)
|
||||
{
|
||||
Genode::log("Sink: packet stream buffers:");
|
||||
debug_print_buffers();
|
||||
start();
|
||||
}
|
||||
|
||||
void process(unsigned cnt)
|
||||
{
|
||||
_cnt = cnt;
|
||||
_operation = OP_PROCESS;
|
||||
_lock.unlock();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void test_1_good_case(Timer::Session *timer, Source *source, Sink *sink,
|
||||
unsigned batch_size, unsigned rounds)
|
||||
{
|
||||
for (unsigned i = 0; i < rounds; i++) {
|
||||
|
||||
enum { DELAY = 200 };
|
||||
|
||||
Genode::log("- round ", i, " -");
|
||||
|
||||
Genode::log("generate ", batch_size, " packets, "
|
||||
"fitting in bulk buffer and submit queue");
|
||||
source->generate(batch_size);
|
||||
|
||||
timer->msleep(DELAY);
|
||||
|
||||
Genode::log("process ", batch_size, " packets");
|
||||
sink->process(batch_size);
|
||||
|
||||
timer->msleep(DELAY);
|
||||
|
||||
Genode::log("acknowledge ", batch_size, " packets");
|
||||
source->acknowledge(batch_size);
|
||||
|
||||
timer->msleep(DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void test_2_flood_submit(Timer::Session *timer, Source *source, Sink *sink)
|
||||
{
|
||||
enum { PACKETS = 9 }; /* more than the number of submit queue entries */
|
||||
enum { DELAY = 200 };
|
||||
|
||||
source->generate(PACKETS);
|
||||
timer->msleep(DELAY);
|
||||
|
||||
Genode::log("- source should block, process 3 packets, source should wake up -");
|
||||
|
||||
sink->process(1);
|
||||
timer->msleep(5*DELAY);
|
||||
sink->process(2);
|
||||
|
||||
Genode::log("- let source acknowledge 3 packets -");
|
||||
source->acknowledge(3);
|
||||
timer->msleep(DELAY);
|
||||
|
||||
Genode::log("- process and acknowledge the remaining packets in batches 3 -\n");
|
||||
for (int i = 0; i < 2; i++) {
|
||||
sink->process(3);
|
||||
timer->msleep(DELAY);
|
||||
|
||||
source->acknowledge(3);
|
||||
timer->msleep(DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
int main(int, char **)
|
||||
{
|
||||
log("--- packet stream test ---");
|
||||
|
||||
Timer::Connection timer;
|
||||
|
||||
enum { TRANSPORT_DS_SIZE = 16*1024 };
|
||||
Dataspace_capability ds_cap = env()->ram_session()->alloc(TRANSPORT_DS_SIZE);
|
||||
|
||||
Source source(ds_cap);
|
||||
Sink sink(ds_cap);
|
||||
|
||||
/* wire data-flow signals beteen source and sink */
|
||||
source.register_sigh_packet_avail(sink.sigh_packet_avail());
|
||||
source.register_sigh_ready_to_ack(sink.sigh_ready_to_ack());
|
||||
sink.register_sigh_ready_to_submit(source.sigh_ready_to_submit());
|
||||
sink.register_sigh_ack_avail(source.sigh_ack_avail());
|
||||
|
||||
timer.msleep(1000);
|
||||
|
||||
log("\n-- test 1: good case, no queue pressure, no blocking --");
|
||||
test_1_good_case(&timer, &source, &sink, 3, 5);
|
||||
|
||||
log("\n-- test 2: flood submit queue, sender blocks, gets woken up --");
|
||||
test_2_flood_submit(&timer, &source, &sink);
|
||||
|
||||
log("waiting to settle down");
|
||||
timer.msleep(2*1000);
|
||||
|
||||
log("--- end of packet stream test ---");
|
||||
return 0;
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
TARGET = test-packet_stream
|
||||
SRC_CC = main.cc
|
||||
LIBS = base
|
Loading…
x
Reference in New Issue
Block a user