port.cc (5476:758c2413765a) | port.cc (5489:94a7bb476fca) |
---|---|
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 */ |
|
42class DefaultPeerPort : public Port 43{ 44 protected: 45 void blowUp() 46 { | 49class DefaultPeerPort : public Port 50{ 51 protected: 52 void blowUp() 53 { |
47 fatal("%s: Unconnected port!", peer->name()); | 54 Port *peer = getPeer(); 55 fatal("unconnected port: %s", peer ? peer->name() : "<unknown>"); |
48 } 49 50 public: | 56 } 57 58 public: |
51 DefaultPeerPort() 52 : Port("default_port") | 59 DefaultPeerPort(Port *_peer) 60 : Port("default_port", NULL, _peer) |
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 | 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 |
91DefaultPeerPort defaultPeerPort; | |
92 | 99 |
93Port::Port() 94 : peer(&defaultPeerPort), owner(NULL) | 100Port::Port(const std::string &_name, MemObject *_owner, Port *_peer) : 101 portName(_name), 102 peer(_peer ? _peer : new DefaultPeerPort(this)), 103 owner(_owner) |
95{ 96} 97 | 104{ 105} 106 |
98Port::Port(const std::string &_name, MemObject *_owner) 99 : portName(_name), peer(&defaultPeerPort), owner(_owner) | 107Port::~Port() |
100{ | 108{ |
109 disconnectFromPeer(); |
|
101} 102 | 110} 111 |
103Port::~Port() | 112void 113Port::disconnectFromPeer() |
104{ | 114{ |
115 if (peer) { 116 assert(peer->getPeer() == this); 117 peer->disconnect(); 118 } |
|
105} 106 107void | 119} 120 121void |
108Port::setPeer(Port *port) | 122Port::disconnect() |
109{ | 123{ |
110 DPRINTF(Config, "setting peer to %s\n", port->name()); 111 112 peer = port; | 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); |
113} 114 115void | 136} 137 138void |
116Port::removeConn() | 139Port::setPeer(Port *port) |
117{ | 140{ |
118 if (peer->getOwner()) 119 peer->getOwner()->deletePortRefs(peer); 120 peer = NULL; | 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; |
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 --- | 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 --- |