TimeSource: Rework SlaveNodes management using TMap.

Signed-off-by: Jérôme Duval <[email protected]>
This commit is contained in:
Dario Casalinuovo
2015-03-17 21:50:25 +01:00
committed by Jérôme Duval
parent fc601b54ff
commit faa2d10c3d
+92 -54
View File
@@ -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) {
if (fSlaveNodes->CountSlaves() == 1) {
// start the time source // start the time source
time_source_op_info msg; time_source_op_info msg;
msg.op = B_TIMESOURCE_START; msg.op = B_TIMESOURCE_START;
msg.real_time = RealTime(); msg.real_time = RealTime();
TRACE_TIMESOURCE("starting time source %" B_PRId32 "\n", ID()); TRACE_TIMESOURCE("starting time source %" B_PRId32 "\n", ID());
write_port(fControlPort, TIMESOURCE_OP, &msg, sizeof(msg)); write_port(fControlPort, TIMESOURCE_OP, &msg, sizeof(msg));
} }
return;
} }
}
ERROR("BTimeSource::DirectAddMe failed\n");
}
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) {
if (fSlaveNodes->CountSlaves() == 0) {
// stop the time source // stop the time source
time_source_op_info msg; time_source_op_info msg;
msg.op = B_TIMESOURCE_STOP_IMMEDIATELY; msg.op = B_TIMESOURCE_STOP_IMMEDIATELY;
msg.real_time = RealTime(); msg.real_time = RealTime();
TRACE_TIMESOURCE("stopping time source %" B_PRId32 "\n", ID()); TRACE_TIMESOURCE("stopping time source %" B_PRId32 "\n", ID());
write_port(fControlPort, TIMESOURCE_OP, &msg, sizeof(msg)); write_port(fControlPort, TIMESOURCE_OP, &msg, sizeof(msg));
} }
return;
}
}
ERROR("BTimeSource::DirectRemoveMe failed\n");
} }
void void
BTimeSource::DirectStart(bigtime_t at) BTimeSource::DirectStart(bigtime_t at)
{ {