TimeSource: Rework SlaveNodes management using TMap.
Signed-off-by: Jérôme Duval <[email protected]>
This commit is contained in:
committed by
Jérôme Duval
parent
fc601b54ff
commit
faa2d10c3d
+112
-74
@@ -2,7 +2,9 @@
|
|||||||
* Copyright 2002-2012, Haiku. All Rights Reserved.
|
* Copyright 2002-2012, Haiku. All Rights Reserved.
|
||||||
* This file may be used under the terms of the MIT License.
|
* This file may be used under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Author: Marcus Overhagen
|
* Authors:
|
||||||
|
* Dario Casalinuovo
|
||||||
|
* Marcus Overhagen
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -16,6 +18,7 @@
|
|||||||
#include "DataExchange.h"
|
#include "DataExchange.h"
|
||||||
#include "ServerInterface.h"
|
#include "ServerInterface.h"
|
||||||
#include "TimeSourceObject.h"
|
#include "TimeSourceObject.h"
|
||||||
|
#include "TMap.h"
|
||||||
|
|
||||||
#define DEBUG_TIMESOURCE 0
|
#define DEBUG_TIMESOURCE 0
|
||||||
|
|
||||||
@@ -45,39 +48,75 @@ struct TimeSourceTransmit
|
|||||||
float drift[TS_INDEX_COUNT];
|
float drift[TS_INDEX_COUNT];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SLAVE_NODES_COUNT 300
|
#define MAX_SLAVE_NODES 300
|
||||||
|
|
||||||
// XXX TODO: storage for slave nodes uses public data members, this should be changed
|
|
||||||
|
|
||||||
class SlaveNodes
|
class SlaveNodes : public BLocker
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SlaveNodes();
|
SlaveNodes();
|
||||||
~SlaveNodes();
|
~SlaveNodes();
|
||||||
public:
|
|
||||||
BLocker * locker;
|
int32 CountSlaves() const;
|
||||||
int32 count;
|
bool GetNextSlave(port_id** id);
|
||||||
media_node_id node_id[SLAVE_NODES_COUNT];
|
void Rewind();
|
||||||
port_id node_port[SLAVE_NODES_COUNT];
|
|
||||||
|
bool InsertSlave(const media_node& node);
|
||||||
|
bool RemoveSlave(const media_node& node);
|
||||||
|
private:
|
||||||
|
Map<media_node_id, port_id> fSlaveList;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
SlaveNodes::SlaveNodes()
|
SlaveNodes::SlaveNodes()
|
||||||
|
:
|
||||||
|
BLocker("BTimeSource slavenodes")
|
||||||
{
|
{
|
||||||
locker = new BLocker("BTimeSource SlaveNodes");
|
|
||||||
count = 0;
|
|
||||||
memset(node_id, 0, sizeof(node_id));
|
|
||||||
memset(node_port, 0, sizeof(node_port));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SlaveNodes::~SlaveNodes()
|
SlaveNodes::~SlaveNodes()
|
||||||
{
|
{
|
||||||
delete locker;
|
fSlaveList.MakeEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} }
|
int32
|
||||||
|
SlaveNodes::CountSlaves() const
|
||||||
|
{
|
||||||
|
return fSlaveList.CountItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
SlaveNodes::GetNextSlave(port_id** id)
|
||||||
|
{
|
||||||
|
return fSlaveList.GetNext(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
SlaveNodes::Rewind()
|
||||||
|
{
|
||||||
|
fSlaveList.Rewind();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
SlaveNodes::InsertSlave(const media_node& node)
|
||||||
|
{
|
||||||
|
return fSlaveList.Insert(node.node, node.port);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
SlaveNodes::RemoveSlave(const media_node& node)
|
||||||
|
{
|
||||||
|
return fSlaveList.Remove(node.node);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} } // namespace BPrivate::media
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
@@ -343,17 +382,17 @@ BTimeSource::BroadcastTimeWarp(bigtime_t at_real_time,
|
|||||||
", new_performance_time %" B_PRId64 "\n", at_real_time,
|
", new_performance_time %" B_PRId64 "\n", at_real_time,
|
||||||
new_performance_time);
|
new_performance_time);
|
||||||
|
|
||||||
BAutolock lock(fSlaveNodes->locker);
|
BAutolock lock(fSlaveNodes);
|
||||||
|
|
||||||
for (int i = 0, n = 0; i < SLAVE_NODES_COUNT && n != fSlaveNodes->count; i++) {
|
port_id* port = NULL;
|
||||||
if (fSlaveNodes->node_id[i] != 0) {
|
while (fSlaveNodes->GetNextSlave(&port) == true) {
|
||||||
node_time_warp_command cmd;
|
node_time_warp_command cmd;
|
||||||
cmd.at_real_time = at_real_time;
|
cmd.at_real_time = at_real_time;
|
||||||
cmd.to_performance_time = new_performance_time;
|
cmd.to_performance_time = new_performance_time;
|
||||||
SendToPort(fSlaveNodes->node_port[i], NODE_TIME_WARP, &cmd, sizeof(cmd));
|
SendToPort(*port, NODE_TIME_WARP,
|
||||||
n++;
|
&cmd, sizeof(cmd));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
fSlaveNodes->Rewind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -365,16 +404,16 @@ BTimeSource::SendRunMode(run_mode mode)
|
|||||||
|
|
||||||
// send the run mode change to all slaved nodes
|
// send the run mode change to all slaved nodes
|
||||||
|
|
||||||
BAutolock lock(fSlaveNodes->locker);
|
BAutolock lock(fSlaveNodes);
|
||||||
|
|
||||||
for (int i = 0, n = 0; i < SLAVE_NODES_COUNT && n != fSlaveNodes->count; i++) {
|
port_id* port = NULL;
|
||||||
if (fSlaveNodes->node_id[i] != 0) {
|
while (fSlaveNodes->GetNextSlave(&port) == true) {
|
||||||
node_set_run_mode_command cmd;
|
node_set_run_mode_command cmd;
|
||||||
cmd.mode = mode;
|
cmd.mode = mode;
|
||||||
SendToPort(fSlaveNodes->node_port[i], NODE_SET_RUN_MODE, &cmd, sizeof(cmd));
|
SendToPort(*port, NODE_SET_RUN_MODE,
|
||||||
n++;
|
&cmd, sizeof(cmd));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
fSlaveNodes->Rewind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -420,9 +459,8 @@ BTimeSource::BTimeSource(media_node_id id)
|
|||||||
// BPrivate::media::TimeSourceObject objects
|
// BPrivate::media::TimeSourceObject objects
|
||||||
// We create a clone of the communication area.
|
// We create a clone of the communication area.
|
||||||
char name[32];
|
char name[32];
|
||||||
area_id area;
|
|
||||||
sprintf(name, "__timesource_buf_%" B_PRId32, id);
|
sprintf(name, "__timesource_buf_%" B_PRId32, id);
|
||||||
area = find_area(name);
|
area_id area = find_area(name);
|
||||||
if (area <= 0) {
|
if (area <= 0) {
|
||||||
ERROR("BTimeSource::BTimeSource couldn't find area, node %" B_PRId32
|
ERROR("BTimeSource::BTimeSource couldn't find area, node %" B_PRId32
|
||||||
"\n", id);
|
"\n", id);
|
||||||
@@ -512,34 +550,34 @@ BTimeSource::DirectAddMe(const media_node& node)
|
|||||||
|
|
||||||
CALLED();
|
CALLED();
|
||||||
ASSERT(fSlaveNodes != NULL);
|
ASSERT(fSlaveNodes != NULL);
|
||||||
BAutolock lock(fSlaveNodes->locker);
|
BAutolock lock(fSlaveNodes);
|
||||||
|
|
||||||
if (fSlaveNodes->count == SLAVE_NODES_COUNT) {
|
if (fSlaveNodes->CountSlaves() == MAX_SLAVE_NODES) {
|
||||||
ERROR("BTimeSource::DirectAddMe out of slave node slots\n");
|
ERROR("BTimeSource::DirectAddMe reached maximum number of slaves\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fNodeID == node.node) {
|
if (fNodeID == node.node) {
|
||||||
ERROR("BTimeSource::DirectAddMe should not add itself to slave nodes\n");
|
ERROR("BTimeSource::DirectAddMe should not add itself to slave nodes\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < SLAVE_NODES_COUNT; i++) {
|
|
||||||
if (fSlaveNodes->node_id[i] == 0) {
|
if (fSlaveNodes->InsertSlave(node) != true) {
|
||||||
fSlaveNodes->node_id[i] = node.node;
|
ERROR("BTimeSource::DirectAddMe failed\n");
|
||||||
fSlaveNodes->node_port[i] = node.port;
|
return;
|
||||||
fSlaveNodes->count += 1;
|
|
||||||
if (fSlaveNodes->count == 1) {
|
|
||||||
// start the time source
|
|
||||||
time_source_op_info msg;
|
|
||||||
msg.op = B_TIMESOURCE_START;
|
|
||||||
msg.real_time = RealTime();
|
|
||||||
TRACE_TIMESOURCE("starting time source %" B_PRId32 "\n", ID());
|
|
||||||
write_port(fControlPort, TIMESOURCE_OP, &msg, sizeof(msg));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ERROR("BTimeSource::DirectAddMe failed\n");
|
|
||||||
}
|
if (fSlaveNodes->CountSlaves() == 1) {
|
||||||
|
// start the time source
|
||||||
|
time_source_op_info msg;
|
||||||
|
msg.op = B_TIMESOURCE_START;
|
||||||
|
msg.real_time = RealTime();
|
||||||
|
|
||||||
|
TRACE_TIMESOURCE("starting time source %" B_PRId32 "\n", ID());
|
||||||
|
|
||||||
|
write_port(fControlPort, TIMESOURCE_OP, &msg, sizeof(msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BTimeSource::DirectRemoveMe(const media_node& node)
|
BTimeSource::DirectRemoveMe(const media_node& node)
|
||||||
@@ -549,31 +587,31 @@ BTimeSource::DirectRemoveMe(const media_node& node)
|
|||||||
|
|
||||||
CALLED();
|
CALLED();
|
||||||
ASSERT(fSlaveNodes != NULL);
|
ASSERT(fSlaveNodes != NULL);
|
||||||
BAutolock lock(fSlaveNodes->locker);
|
BAutolock lock(fSlaveNodes);
|
||||||
|
|
||||||
if (fSlaveNodes->count == 0) {
|
if (fSlaveNodes->CountSlaves() == 0) {
|
||||||
ERROR("BTimeSource::DirectRemoveMe no slots used\n");
|
ERROR("BTimeSource::DirectRemoveMe no slots used\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < SLAVE_NODES_COUNT; i++) {
|
|
||||||
if (fSlaveNodes->node_id[i] == node.node && fSlaveNodes->node_port[i] == node.port) {
|
if (fSlaveNodes->RemoveSlave(node) != true) {
|
||||||
fSlaveNodes->node_id[i] = 0;
|
ERROR("BTimeSource::DirectRemoveMe failed\n");
|
||||||
fSlaveNodes->node_port[i] = 0;
|
return;
|
||||||
fSlaveNodes->count -= 1;
|
}
|
||||||
if (fSlaveNodes->count == 0) {
|
|
||||||
// stop the time source
|
if (fSlaveNodes->CountSlaves() == 0) {
|
||||||
time_source_op_info msg;
|
// stop the time source
|
||||||
msg.op = B_TIMESOURCE_STOP_IMMEDIATELY;
|
time_source_op_info msg;
|
||||||
msg.real_time = RealTime();
|
msg.op = B_TIMESOURCE_STOP_IMMEDIATELY;
|
||||||
TRACE_TIMESOURCE("stopping time source %" B_PRId32 "\n", ID());
|
msg.real_time = RealTime();
|
||||||
write_port(fControlPort, TIMESOURCE_OP, &msg, sizeof(msg));
|
|
||||||
}
|
TRACE_TIMESOURCE("stopping time source %" B_PRId32 "\n", ID());
|
||||||
return;
|
|
||||||
}
|
write_port(fControlPort, TIMESOURCE_OP, &msg, sizeof(msg));
|
||||||
}
|
}
|
||||||
ERROR("BTimeSource::DirectRemoveMe failed\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BTimeSource::DirectStart(bigtime_t at)
|
BTimeSource::DirectStart(bigtime_t at)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user