port.cc (5489:94a7bb476fca) | port.cc (5494:85c8d296c1cb) |
---|---|
1/* 2 * Copyright (c) 2002-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 25 unchanged lines hidden (view full) --- 34 */ 35#include <cstring> 36 37#include "base/chunk_generator.hh" 38#include "base/trace.hh" 39#include "mem/mem_object.hh" 40#include "mem/port.hh" 41 | 1/* 2 * Copyright (c) 2002-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; --- 25 unchanged lines hidden (view full) --- 34 */ 35#include <cstring> 36 37#include "base/chunk_generator.hh" 38#include "base/trace.hh" 39#include "mem/mem_object.hh" 40#include "mem/port.hh" 41 |
42/** 43 * Special class for port objects that are used as peers for 44 * unconnected ports. Assigning instances of this class to newly 45 * allocated ports allows us to guarantee that every port has a peer 46 * object (so there's no need to check for null peer pointers), while 47 * catching uses of unconnected ports. 48 */ | |
49class DefaultPeerPort : public Port 50{ 51 protected: 52 void blowUp() 53 { | 42class DefaultPeerPort : public Port 43{ 44 protected: 45 void blowUp() 46 { |
54 Port *peer = getPeer(); 55 fatal("unconnected port: %s", peer ? peer->name() : "<unknown>"); | 47 fatal("%s: Unconnected port!", peer->name()); |
56 } 57 58 public: | 48 } 49 50 public: |
59 DefaultPeerPort(Port *_peer) 60 : Port("default_port", NULL, _peer) | 51 DefaultPeerPort() 52 : Port("default_port") |
61 { } 62 63 bool recvTiming(PacketPtr) 64 { 65 blowUp(); 66 return false; 67 } 68 --- 22 unchanged lines hidden (view full) --- 91 void getDeviceAddressRanges(AddrRangeList &, bool &) 92 { 93 blowUp(); 94 } 95 96 bool isDefaultPort() const { return true; } 97}; 98 | 53 { } 54 55 bool recvTiming(PacketPtr) 56 { 57 blowUp(); 58 return false; 59 } 60 --- 22 unchanged lines hidden (view full) --- 83 void getDeviceAddressRanges(AddrRangeList &, bool &) 84 { 85 blowUp(); 86 } 87 88 bool isDefaultPort() const { return true; } 89}; 90 |
91DefaultPeerPort defaultPeerPort; |
|
99 | 92 |
100Port::Port(const std::string &_name, MemObject *_owner, Port *_peer) : 101 portName(_name), 102 peer(_peer ? _peer : new DefaultPeerPort(this)), 103 owner(_owner) | 93Port::Port() 94 : peer(&defaultPeerPort), owner(NULL) |
104{ 105} 106 | 95{ 96} 97 |
107Port::~Port() | 98Port::Port(const std::string &_name, MemObject *_owner) 99 : portName(_name), peer(&defaultPeerPort), owner(_owner) |
108{ | 100{ |
109 disconnectFromPeer(); | |
110} 111 | 101} 102 |
112void 113Port::disconnectFromPeer() | 103Port::~Port() |
114{ | 104{ |
115 if (peer) { 116 assert(peer->getPeer() == this); 117 peer->disconnect(); 118 } | |
119} 120 121void | 105} 106 107void |
122Port::disconnect() | 108Port::setPeer(Port *port) |
123{ | 109{ |
124 // This notification should come only from our peer, so we must 125 // have one, 126 assert(peer != NULL); 127 // We must clear 'peer' here, else if owner->deletePort() calls 128 // delete on us then we'll recurse infinitely through the Port 129 // destructor. 130 peer = NULL; 131 // If owner->deletePort() returns true, then we've been deleted, 132 // so don't do anything but get out of here. If not, reset peer 133 // pointer to a DefaultPeerPort. 134 if (!(owner && owner->deletePort(this))) 135 peer = new DefaultPeerPort(this); | 110 DPRINTF(Config, "setting peer to %s\n", port->name()); 111 112 peer = port; |
136} 137 138void | 113} 114 115void |
139Port::setPeer(Port *port) | 116Port::removeConn() |
140{ | 117{ |
141 DPRINTF(Config, "setting peer to %s, old peer %s\n", 142 port->name(), peer ? peer->name() : "<null>"); 143 144 // You'd think we'd want to disconnect from the previous peer 145 // here, but it turns out that with some functional ports the old 146 // peer keeps using the connection, and it works because 147 // functional ports are unidirectional. 148 // 149 // disconnectFromPeer(); 150 151 peer = port; | 118 if (peer->getOwner()) 119 peer->getOwner()->deletePortRefs(peer); 120 peer = NULL; |
152} 153 154void 155Port::blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd) 156{ 157 Request req; 158 159 for (ChunkGenerator gen(addr, size, peerBlockSize()); --- 44 unchanged lines hidden --- | 121} 122 123void 124Port::blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd) 125{ 126 Request req; 127 128 for (ChunkGenerator gen(addr, size, peerBlockSize()); --- 44 unchanged lines hidden --- |