Ticket #11852: 0003-TimeSource-Rework-SlaveNodes-management-using-TMap.patch

File 0003-TimeSource-Rework-SlaveNodes-management-using-TMap.patch, 7.4 KB (added by Barrett, 9 years ago)
  • src/kits/media/TimeSource.cpp

    From 9ab7a7fb13136fe95b59e7a81a2343019de7919d Mon Sep 17 00:00:00 2001
    From: Dario Casalinuovo <b.vitruvio@gmail.com>
    Date: Tue, 17 Mar 2015 21:03:17 +0100
    Subject: [PATCH 3/3] TimeSource: Rework SlaveNodes management using TMap.
    
    ---
     src/kits/media/TimeSource.cpp | 186 +++++++++++++++++++++++++-----------------
     1 file changed, 112 insertions(+), 74 deletions(-)
    
    diff --git a/src/kits/media/TimeSource.cpp b/src/kits/media/TimeSource.cpp
    index 3ceee37..f3f6ad2 100644
    a b  
    22 * Copyright 2002-2012, Haiku. All Rights Reserved.
    33 * This file may be used under the terms of the MIT License.
    44 *
    5  * Author: Marcus Overhagen
     5 * Authors:
     6 *    Dario Casalinuovo
     7 *    Marcus Overhagen
    68 */
    79
    810
     
    1618#include "DataExchange.h"
    1719#include "ServerInterface.h"
    1820#include "TimeSourceObject.h"
     21#include "TMap.h"
    1922
    2023#define DEBUG_TIMESOURCE 0
    2124
    struct TimeSourceTransmit  
    4548    float drift[TS_INDEX_COUNT];
    4649};
    4750
    48 #define SLAVE_NODES_COUNT 300
     51#define MAX_SLAVE_NODES 300
    4952
    50 // XXX TODO: storage for slave nodes uses public data members, this should be changed
    5153
    52 class SlaveNodes
     54class SlaveNodes : public BLocker
    5355{
    5456public:
    55                     SlaveNodes();
    56                     ~SlaveNodes();
    57 public:
    58     BLocker *       locker;
    59     int32           count;
    60     media_node_id   node_id[SLAVE_NODES_COUNT];
    61     port_id         node_port[SLAVE_NODES_COUNT];
     57                                SlaveNodes();
     58                                ~SlaveNodes();
     59
     60    int32                       CountSlaves() const;
     61    bool                        GetNextSlave(port_id** id);
     62    void                        Rewind();
     63
     64    bool                        InsertSlave(const media_node& node);
     65    bool                        RemoveSlave(const media_node& node);
     66private:
     67    Map<media_node_id, port_id> fSlaveList;
    6268};
    6369
    6470
    6571SlaveNodes::SlaveNodes()
     72    :
     73    BLocker("BTimeSource slavenodes")
    6674{
    67     locker = new BLocker("BTimeSource SlaveNodes");
    68     count = 0;
    69     memset(node_id, 0, sizeof(node_id));
    70     memset(node_port, 0, sizeof(node_port));
    7175}
    7276
    7377
    7478SlaveNodes::~SlaveNodes()
    7579{
    76     delete locker;
     80    fSlaveList.MakeEmpty();
     81}
     82
     83
     84int32
     85SlaveNodes::CountSlaves() const
     86{
     87    return fSlaveList.CountItems();
     88}
     89
     90
     91bool
     92SlaveNodes::GetNextSlave(port_id** id)
     93{
     94    return fSlaveList.GetNext(id);
    7795}
    7896
    7997
    80 } }
     98void
     99SlaveNodes::Rewind()
     100{
     101    fSlaveList.Rewind();
     102}
     103
     104
     105bool
     106SlaveNodes::InsertSlave(const media_node& node)
     107{
     108    return fSlaveList.Insert(node.node, node.port);
     109}
     110
     111
     112bool
     113SlaveNodes::RemoveSlave(const media_node& node)
     114{
     115    return fSlaveList.Remove(node.node);
     116}
     117
     118
     119} } // namespace BPrivate::media
    81120
    82121
    83122/*************************************************************
    BTimeSource::BroadcastTimeWarp(bigtime_t at_real_time,  
    343382        ", new_performance_time %" B_PRId64 "\n", at_real_time,
    344383        new_performance_time);
    345384
    346     BAutolock lock(fSlaveNodes->locker);
     385    BAutolock lock(fSlaveNodes);
    347386
    348     for (int i = 0, n = 0; i < SLAVE_NODES_COUNT && n != fSlaveNodes->count; i++) {
    349         if (fSlaveNodes->node_id[i] != 0) {
    350             node_time_warp_command cmd;
    351             cmd.at_real_time = at_real_time;
    352             cmd.to_performance_time = new_performance_time;
    353             SendToPort(fSlaveNodes->node_port[i], NODE_TIME_WARP, &cmd, sizeof(cmd));
    354             n++;
    355         }
     387    port_id* port = NULL;
     388    while (fSlaveNodes->GetNextSlave(&port) == true) {
     389        node_time_warp_command cmd;
     390        cmd.at_real_time = at_real_time;
     391        cmd.to_performance_time = new_performance_time;
     392        SendToPort(*port, NODE_TIME_WARP,
     393            &cmd, sizeof(cmd));
    356394    }
     395    fSlaveNodes->Rewind();
    357396}
    358397
    359398
    BTimeSource::SendRunMode(run_mode mode)  
    365404
    366405    // send the run mode change to all slaved nodes
    367406
    368     BAutolock lock(fSlaveNodes->locker);
     407    BAutolock lock(fSlaveNodes);
    369408
    370     for (int i = 0, n = 0; i < SLAVE_NODES_COUNT && n != fSlaveNodes->count; i++) {
    371         if (fSlaveNodes->node_id[i] != 0) {
    372             node_set_run_mode_command cmd;
    373             cmd.mode = mode;
    374             SendToPort(fSlaveNodes->node_port[i], NODE_SET_RUN_MODE, &cmd, sizeof(cmd));
    375             n++;
    376         }
     409    port_id* port = NULL;
     410    while (fSlaveNodes->GetNextSlave(&port) == true) {
     411        node_set_run_mode_command cmd;
     412        cmd.mode = mode;
     413        SendToPort(*port, NODE_SET_RUN_MODE,
     414            &cmd, sizeof(cmd));
    377415    }
     416    fSlaveNodes->Rewind();
    378417}
    379418
    380419
    BTimeSource::BTimeSource(media_node_id id)  
    420459    // BPrivate::media::TimeSourceObject objects
    421460    // We create a clone of the communication area.
    422461    char name[32];
    423     area_id area;
    424462    sprintf(name, "__timesource_buf_%" B_PRId32, id);
    425     area = find_area(name);
     463    area_id area = find_area(name);
    426464    if (area <= 0) {
    427465        ERROR("BTimeSource::BTimeSource couldn't find area, node %" B_PRId32
    428466            "\n", id);
    BTimeSource::DirectAddMe(const media_node& node)  
    512550
    513551    CALLED();
    514552    ASSERT(fSlaveNodes != NULL);
    515     BAutolock lock(fSlaveNodes->locker);
     553    BAutolock lock(fSlaveNodes);
    516554
    517     if (fSlaveNodes->count == SLAVE_NODES_COUNT) {
    518         ERROR("BTimeSource::DirectAddMe out of slave node slots\n");
     555    if (fSlaveNodes->CountSlaves() == MAX_SLAVE_NODES) {
     556        ERROR("BTimeSource::DirectAddMe reached maximum number of slaves\n");
    519557        return;
    520558    }
    521559    if (fNodeID == node.node) {
    522560        ERROR("BTimeSource::DirectAddMe should not add itself to slave nodes\n");
    523561        return;
    524562    }
    525     for (int i = 0; i < SLAVE_NODES_COUNT; i++) {
    526         if (fSlaveNodes->node_id[i] == 0) {
    527             fSlaveNodes->node_id[i] = node.node;
    528             fSlaveNodes->node_port[i] = node.port;
    529             fSlaveNodes->count += 1;
    530             if (fSlaveNodes->count == 1) {
    531                 // start the time source
    532                 time_source_op_info msg;
    533                 msg.op = B_TIMESOURCE_START;
    534                 msg.real_time = RealTime();
    535                 TRACE_TIMESOURCE("starting time source %" B_PRId32 "\n", ID());
    536                 write_port(fControlPort, TIMESOURCE_OP, &msg, sizeof(msg));
    537             }
    538             return;
    539         }
     563
     564    if (fSlaveNodes->InsertSlave(node) != true) {
     565        ERROR("BTimeSource::DirectAddMe failed\n");
     566        return;
    540567    }
    541     ERROR("BTimeSource::DirectAddMe failed\n");
    542 }
     568
     569    if (fSlaveNodes->CountSlaves() == 1) {
     570        // start the time source
     571        time_source_op_info msg;
     572        msg.op = B_TIMESOURCE_START;
     573        msg.real_time = RealTime();
     574
     575        TRACE_TIMESOURCE("starting time source %" B_PRId32 "\n", ID());
     576
     577        write_port(fControlPort, TIMESOURCE_OP, &msg, sizeof(msg));
     578    }
     579 }
     580
    543581
    544582void
    545583BTimeSource::DirectRemoveMe(const media_node& node)
    BTimeSource::DirectRemoveMe(const media_node& node)  
    549587
    550588    CALLED();
    551589    ASSERT(fSlaveNodes != NULL);
    552     BAutolock lock(fSlaveNodes->locker);
     590    BAutolock lock(fSlaveNodes);
    553591
    554     if (fSlaveNodes->count == 0) {
     592    if (fSlaveNodes->CountSlaves() == 0) {
    555593        ERROR("BTimeSource::DirectRemoveMe no slots used\n");
    556594        return;
    557595    }
    558     for (int i = 0; i < SLAVE_NODES_COUNT; i++) {
    559         if (fSlaveNodes->node_id[i] == node.node && fSlaveNodes->node_port[i] == node.port) {
    560             fSlaveNodes->node_id[i] = 0;
    561             fSlaveNodes->node_port[i] = 0;
    562             fSlaveNodes->count -= 1;
    563             if (fSlaveNodes->count == 0) {
    564                 // stop the time source
    565                 time_source_op_info msg;
    566                 msg.op = B_TIMESOURCE_STOP_IMMEDIATELY;
    567                 msg.real_time = RealTime();
    568                 TRACE_TIMESOURCE("stopping time source %" B_PRId32 "\n", ID());
    569                 write_port(fControlPort, TIMESOURCE_OP, &msg, sizeof(msg));
    570             }
    571             return;
    572         }
     596
     597    if (fSlaveNodes->RemoveSlave(node) != true) {
     598        ERROR("BTimeSource::DirectRemoveMe failed\n");
     599        return;
     600    }
     601
     602    if (fSlaveNodes->CountSlaves() == 0) {
     603        // stop the time source
     604        time_source_op_info msg;
     605        msg.op = B_TIMESOURCE_STOP_IMMEDIATELY;
     606        msg.real_time = RealTime();
     607
     608        TRACE_TIMESOURCE("stopping time source %" B_PRId32 "\n", ID());
     609
     610        write_port(fControlPort, TIMESOURCE_OP, &msg, sizeof(msg));
    573611    }
    574     ERROR("BTimeSource::DirectRemoveMe failed\n");
    575612}
    576613
     614
    577615void
    578616BTimeSource::DirectStart(bigtime_t at)
    579617{