Project

General

Profile

Statistics
| Branch: | Revision:

root / src / sim / parsim / cadvlinkdelaylookahead.cc @ 81ad8b66

History | View | Annotate | Download (5.12 KB)

1
//=========================================================================
2
//  CLINKDELAYLOOKAHEAD.CC - part of
3
//
4
//                  OMNeT++/OMNEST
5
//           Discrete System Simulation in C++
6
//
7
//  Author: Andras Varga, 2003
8
//          Dept. of Electrical and Computer Systems Engineering,
9
//          Monash University, Melbourne, Australia
10
//
11
//=========================================================================
12

    
13
/*--------------------------------------------------------------*
14
  Copyright (C) 2003-2008 Andras Varga
15
  Copyright (C) 2006-2008 OpenSim Ltd.
16

17
  This file is distributed WITHOUT ANY WARRANTY. See the file
18
  `license' for details on this and other legal matters.
19
*--------------------------------------------------------------*/
20

    
21

    
22
#include "cadvlinkdelaylookahead.h"
23
#include "csimulation.h"
24
#include "cmessage.h"
25
#include "cenvir.h"
26
#include "cnullmessageprot.h"
27
#include "cparsimcomm.h"
28
#include "cparsimpartition.h"
29
#include "cplaceholdermod.h"
30
#include "cproxygate.h"
31
#include "cchannel.h"
32
#include "globals.h"
33
#include "regmacros.h"
34

    
35
USING_NAMESPACE
36

    
37

    
38
Register_Class(cAdvancedLinkDelayLookahead);
39

    
40

    
41
cAdvancedLinkDelayLookahead::cAdvancedLinkDelayLookahead()
42
{
43
    numSeg = 0;
44
    segInfo = NULL;
45
}
46

    
47
cAdvancedLinkDelayLookahead::~cAdvancedLinkDelayLookahead()
48
{
49
    delete [] segInfo;
50
}
51

    
52
void cAdvancedLinkDelayLookahead::startRun()
53
{
54
    ev << "starting Link Delay Lookahead...\n";
55

    
56
    delete [] segInfo;
57

    
58
    numSeg = comm->getNumPartitions();
59
    segInfo = new PartitionInfo[numSeg];
60
    int myProcId = comm->getProcId();
61

    
62
    char buf[30];
63

    
64
    // temporarily initialize everything to zero.
65
    for (int i=0; i<numSeg; i++)
66
    {
67
        segInfo[i].numLinks = 0;
68
        segInfo[i].links = NULL;
69
    }
70

    
71
    // fill numLinks and links[]
72
    ev << "  collecting links...\n";
73

    
74
    // step 1: count gates
75
    for (int modId=0; modId<=sim->getLastModuleId(); modId++)
76
    {
77
        cPlaceholderModule *mod = dynamic_cast<cPlaceholderModule *>(sim->getModule(modId));
78
        if (mod)
79
        {
80
            for (cModule::GateIterator i(mod); !i.end(); i++)
81
            {
82
                cGate *g = i();
83
                cProxyGate *pg  = dynamic_cast<cProxyGate *>(g);
84
                if (pg && pg->getPreviousGate() && pg->getRemoteProcId()>=0)
85
                    segInfo[pg->getRemoteProcId()].numLinks++;
86
            }
87
        }
88
    }
89

    
90
    // step 2: allocate links[]
91
    for (int i=0; i<numSeg; i++)
92
    {
93
        int numLinks = segInfo[i].numLinks;
94
        segInfo[i].links = new LinkOut *[numLinks];
95
        for (int k=0; k<numLinks; k++)
96
            segInfo[i].links[k] = NULL;
97
    }
98

    
99
    // step 3: fill in
100
    for (int modId=0; modId<=sim->getLastModuleId(); modId++)
101
    {
102
        cPlaceholderModule *mod = dynamic_cast<cPlaceholderModule *>(sim->getModule(modId));
103
        if (mod)
104
        {
105
            for (cModule::GateIterator i(mod); !i.end(); i++)
106
            {
107
                // if this is a properly connected proxygate, process it
108
                // FIXME leave out gates from other cPlaceholderModules
109
                cGate *g = i();
110
                cProxyGate *pg  = dynamic_cast<cProxyGate *>(g);
111
                if (pg && pg->getPreviousGate() && pg->getRemoteProcId()>=0)
112
                {
113
                    // check we have a delay on this link (it gives us lookahead)
114
                    cGate *fromg  = pg->getPreviousGate();
115
                    cChannel *chan = fromg ? fromg->getChannel() : NULL;
116
                    cDatarateChannel *datarateChan = dynamic_cast<cDatarateChannel *>(chan);
117
                    cPar *delaypar = datarateChan ? datarateChan->getDelay() : NULL;
118
                    double linkDelay = delaypar ? delaypar->doubleValue() : 0;
119
                    if (linkDelay<=0.0)
120
                        throw cRuntimeError("cAdvancedLinkDelayLookahead: zero delay on link from gate `%s', no lookahead for parallel simulation", fromg->getFullPath().c_str());
121

    
122
                    // store
123
                    int procId = pg->getRemoteProcId();
124
                    int k=0;
125
                    while (segInfo[procId].links[k]) k++; // find 1st empty slot
126
                    LinkOut *link = new LinkOut;
127
                    segInfo[procId].links[k] = link;
128
                    pg->setSynchData(link);
129
                    link->lookahead = linkDelay;
130
                    link->eot = 0.0;
131

    
132
                    ev << "    link " << k << " to procId=" << procId << " on gate `" << fromg->getFullPath() <<"': delay=" << linkDelay << "\n";
133
                }
134
            }
135
        }
136
    }
137

    
138
    ev << "  setup done.\n";
139
}
140

    
141
void cAdvancedLinkDelayLookahead::endRun()
142
{
143
}
144

    
145
simtime_t cAdvancedLinkDelayLookahead::getCurrentLookahead(cMessage *msg, int procId, void *data)
146
{
147
    // find LinkOut structure in segInfo[destProcId].
148
    LinkOut *link = (LinkOut *)data;
149
    if (!link)
150
        throw cRuntimeError("internal parallel simulation error: cProxyGate has no associated data pointer");
151

    
152
    // calculate EOT
153
    simtime_t eot;
154
    simtime_t now = sim->getSimTime();
155
    simtime_t newLinkEot = now + link->lookahead;
156

    
157
    // TBD finish...
158
    return 0.0;
159
}
160

    
161
simtime_t cAdvancedLinkDelayLookahead::getCurrentLookahead(int procId)
162
{
163
    return segInfo[procId].lookahead;
164
}
165

    
166

    
167