part_blk: Improve multiple client support

Increase size of block session backing store so it can handle maximum supported
packet size. Synchronize client threads during packet allocation.

Fixes #276
This commit is contained in:
Sebastian Sumpf 2012-07-11 14:51:42 +02:00 committed by Norman Feske
parent abd09e419f
commit 5f33704155
1 changed files with 30 additions and 18 deletions

View File

@ -11,18 +11,24 @@
* under the terms of the GNU General Public License version 2.
*/
#include <base/allocator_avl.h>
#include <base/semaphore.h>
#include <block_session/connection.h>
#include "part_blk.h"
using namespace Genode;
/**
* Used to block until a packet has been freed
*/
static Semaphore _alloc_sem(0);
namespace Partition {
size_t _blk_cnt;
size_t _blk_size;
Allocator_avl _block_alloc(env()->heap());
Block::Connection _blk(&_block_alloc);
Block::Connection _blk(&_block_alloc, 4 * MAX_PACKET_SIZE);
Partition *_part_list[MAX_PARTITIONS]; /* contains pointers to valid partittions or 0 */
@ -84,15 +90,8 @@ namespace Partition {
Lock::Guard guard(_lock);
Block::Packet_descriptor::Opcode op = write ? Block::Packet_descriptor::WRITE
: Block::Packet_descriptor::READ;
try {
_p = Block::Packet_descriptor( _blk.dma_alloc_packet(_blk_size * count),
_p = Block::Packet_descriptor(_blk.dma_alloc_packet(_blk_size * count),
op, blk_nr, count);
} catch (Block::Session::Tx::Source::Packet_alloc_failed) {
PERR("Packet overrun!");
_p = _blk.tx()->get_acked_packet();
throw Io_error();
}
}
void submit_request()
@ -101,6 +100,10 @@ namespace Partition {
_blk.tx()->submit_packet(_p);
_p = _blk.tx()->get_acked_packet();
/* unblock clients that possibly wait for packet stream allocations */
if (_alloc_sem.cnt() < 0)
_alloc_sem.up();
if (!_p.succeeded()) {
PERR("Could not access block %zu", _p.block_number());
throw Io_error();
@ -198,16 +201,25 @@ namespace Partition {
unsigned long curr_count = min<unsigned long>(count, max_packets());
bytes = curr_count * _blk_size;
bool alloc = false;
while (!alloc) {
try {
Sector sec(lba, curr_count, write);
if (!write) {
sec.submit_request();
memcpy(buf, sec.addr<void *>(), bytes);
}
else {
memcpy(sec.addr<void *>(), buf, bytes);
sec.submit_request();
}
Sector sec(lba, curr_count, write);
if (!write) {
sec.submit_request();
memcpy(buf, sec.addr<void *>(), bytes);
}
else {
memcpy(sec.addr<void *>(), buf, bytes);
sec.submit_request();
alloc = true;
} catch (Block::Session::Tx::Source::Packet_alloc_failed) {
/* block */
_alloc_sem.down();
}
}
lba += curr_count;