Merge zizzer.eecs.umich.edu:/bk/m5
into zans.eecs.umich.edu:/z/binkertn/research/m5/latest --HG-- extra : convert_revision : b4e94c075fdb58f6ac66aedf4f6a8f792988ed13
This commit is contained in:
commit
293ee75117
4 changed files with 178 additions and 115 deletions
|
@ -40,148 +40,174 @@
|
|||
using namespace std;
|
||||
|
||||
CircleBuf::CircleBuf(int l)
|
||||
: rollover(false), buflen(l), size(0), start(0), stop(0)
|
||||
{ buf = new char[buflen]; }
|
||||
: _rollover(false), _buflen(l), _size(0), _start(0), _stop(0)
|
||||
{
|
||||
_buf = new char[_buflen];
|
||||
}
|
||||
|
||||
CircleBuf::~CircleBuf()
|
||||
{ if (buf) delete [] buf; }
|
||||
{
|
||||
if (_buf)
|
||||
delete [] _buf;
|
||||
}
|
||||
|
||||
void
|
||||
CircleBuf::dump()
|
||||
{
|
||||
cprintf("start = %10d, stop = %10d, buflen = %10d\n", start, stop, buflen);
|
||||
fflush(stdout);
|
||||
::write(STDOUT_FILENO, buf, buflen);
|
||||
::write(STDOUT_FILENO, "<\n", 2);
|
||||
cprintf("start = %10d, stop = %10d, buflen = %10d\n",
|
||||
_start, _stop, _buflen);
|
||||
fflush(stdout);
|
||||
::write(STDOUT_FILENO, _buf, _buflen);
|
||||
::write(STDOUT_FILENO, "<\n", 2);
|
||||
}
|
||||
|
||||
void
|
||||
CircleBuf::flush()
|
||||
{
|
||||
start = 0;
|
||||
stop = 0;
|
||||
rollover = false;
|
||||
_start = 0;
|
||||
_stop = 0;
|
||||
_rollover = false;
|
||||
}
|
||||
|
||||
void
|
||||
CircleBuf::read(char *b, int len)
|
||||
{
|
||||
size -= len;
|
||||
if (size < 0)
|
||||
size = 0;
|
||||
_size -= len;
|
||||
if (_size < 0)
|
||||
_size = 0;
|
||||
|
||||
if (stop > start) {
|
||||
len = min(len, stop - start);
|
||||
memcpy(b, buf + start, len);
|
||||
start += len;
|
||||
}
|
||||
else {
|
||||
int endlen = buflen - start;
|
||||
if (endlen > len) {
|
||||
memcpy(b, buf + start, len);
|
||||
start += len;
|
||||
if (_stop > _start) {
|
||||
len = min(len, _stop - _start);
|
||||
memcpy(b, _buf + _start, len);
|
||||
_start += len;
|
||||
}
|
||||
else {
|
||||
memcpy(b, buf + start, endlen);
|
||||
start = min(len - endlen, stop);
|
||||
memcpy(b + endlen, buf, start);
|
||||
int endlen = _buflen - _start;
|
||||
if (endlen > len) {
|
||||
memcpy(b, _buf + _start, len);
|
||||
_start += len;
|
||||
}
|
||||
else {
|
||||
memcpy(b, _buf + _start, endlen);
|
||||
_start = min(len - endlen, _stop);
|
||||
memcpy(b + endlen, _buf, _start);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CircleBuf::read(int fd, int len)
|
||||
{
|
||||
size -= len;
|
||||
if (size < 0)
|
||||
size = 0;
|
||||
_size -= len;
|
||||
if (_size < 0)
|
||||
_size = 0;
|
||||
|
||||
if (stop > start) {
|
||||
len = min(len, stop - start);
|
||||
::write(fd, buf + start, len);
|
||||
start += len;
|
||||
}
|
||||
else {
|
||||
int endlen = buflen - start;
|
||||
if (endlen > len) {
|
||||
::write(fd, buf + start, len);
|
||||
start += len;
|
||||
if (_stop > _start) {
|
||||
len = min(len, _stop - _start);
|
||||
::write(fd, _buf + _start, len);
|
||||
_start += len;
|
||||
}
|
||||
else {
|
||||
::write(fd, buf + start, endlen);
|
||||
start = min(len - endlen, stop);
|
||||
::write(fd, buf, start);
|
||||
int endlen = _buflen - _start;
|
||||
if (endlen > len) {
|
||||
::write(fd, _buf + _start, len);
|
||||
_start += len;
|
||||
}
|
||||
else {
|
||||
::write(fd, _buf + _start, endlen);
|
||||
_start = min(len - endlen, _stop);
|
||||
::write(fd, _buf, _start);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CircleBuf::read(int fd)
|
||||
{
|
||||
size = 0;
|
||||
_size = 0;
|
||||
|
||||
if (stop > start) {
|
||||
::write(fd, buf + start, stop - start);
|
||||
}
|
||||
else {
|
||||
::write(fd, buf + start, buflen - start);
|
||||
::write(fd, buf, stop);
|
||||
}
|
||||
if (_stop > _start) {
|
||||
::write(fd, _buf + _start, _stop - _start);
|
||||
}
|
||||
else {
|
||||
::write(fd, _buf + _start, _buflen - _start);
|
||||
::write(fd, _buf, _stop);
|
||||
}
|
||||
|
||||
start = stop;
|
||||
_start = _stop;
|
||||
}
|
||||
|
||||
void
|
||||
CircleBuf::read(ostream &out)
|
||||
{
|
||||
_size = 0;
|
||||
|
||||
if (_stop > _start) {
|
||||
out.write(_buf + _start, _stop - _start);
|
||||
}
|
||||
else {
|
||||
out.write(_buf + _start, _buflen - _start);
|
||||
out.write(_buf, _stop);
|
||||
}
|
||||
|
||||
_start = _stop;
|
||||
}
|
||||
|
||||
void
|
||||
CircleBuf::readall(int fd)
|
||||
{
|
||||
if (rollover)
|
||||
::write(fd, buf + stop, buflen - stop);
|
||||
if (_rollover)
|
||||
::write(fd, _buf + _stop, _buflen - _stop);
|
||||
|
||||
::write(fd, buf, stop);
|
||||
start = stop;
|
||||
::write(fd, _buf, _stop);
|
||||
_start = _stop;
|
||||
}
|
||||
|
||||
void
|
||||
CircleBuf::write(char b)
|
||||
{ write(&b, 1); }
|
||||
{
|
||||
write(&b, 1);
|
||||
}
|
||||
|
||||
void
|
||||
CircleBuf::write(const char *b)
|
||||
{ write(b, strlen(b)); }
|
||||
{
|
||||
write(b, strlen(b));
|
||||
}
|
||||
|
||||
void
|
||||
CircleBuf::write(const char *b, int len)
|
||||
{
|
||||
if (len <= 0)
|
||||
return;
|
||||
if (len <= 0)
|
||||
return;
|
||||
|
||||
size += len;
|
||||
if (size > buflen)
|
||||
size = buflen;
|
||||
_size += len;
|
||||
if (_size > _buflen)
|
||||
_size = _buflen;
|
||||
|
||||
int old_start = start;
|
||||
int old_stop = stop;
|
||||
int old_start = _start;
|
||||
int old_stop = _stop;
|
||||
|
||||
if (len >= buflen) {
|
||||
start = 0;
|
||||
stop = buflen;
|
||||
rollover = true;
|
||||
memcpy(buf, b + (len - buflen), buflen);
|
||||
return;
|
||||
}
|
||||
if (len >= _buflen) {
|
||||
_start = 0;
|
||||
_stop = _buflen;
|
||||
_rollover = true;
|
||||
memcpy(_buf, b + (len - _buflen), _buflen);
|
||||
return;
|
||||
}
|
||||
|
||||
if (stop + len <= buflen) {
|
||||
memcpy(buf + stop, b, len);
|
||||
stop += len;
|
||||
} else {
|
||||
int end_len = buflen - old_stop;
|
||||
stop = len - end_len;
|
||||
memcpy(buf + old_stop, b, end_len);
|
||||
memcpy(buf, b + end_len, stop);
|
||||
rollover = true;
|
||||
}
|
||||
if (_stop + len <= _buflen) {
|
||||
memcpy(_buf + _stop, b, len);
|
||||
_stop += len;
|
||||
} else {
|
||||
int end_len = _buflen - old_stop;
|
||||
_stop = len - end_len;
|
||||
memcpy(_buf + old_stop, b, end_len);
|
||||
memcpy(_buf, b + end_len, _stop);
|
||||
_rollover = true;
|
||||
}
|
||||
|
||||
if (old_start > old_stop && old_start < stop ||
|
||||
old_start < old_stop && stop < old_stop)
|
||||
start = stop + 1;
|
||||
if (old_start > old_stop && old_start < _stop ||
|
||||
old_start < old_stop && _stop < old_stop)
|
||||
_start = _stop + 1;
|
||||
}
|
||||
|
|
|
@ -29,31 +29,34 @@
|
|||
#ifndef __CIRCLEBUF_HH__
|
||||
#define __CIRCLEBUF_HH__
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
class CircleBuf
|
||||
{
|
||||
protected:
|
||||
char *buf;
|
||||
bool rollover;
|
||||
int buflen;
|
||||
int size;
|
||||
int start;
|
||||
int stop;
|
||||
protected:
|
||||
char *_buf;
|
||||
bool _rollover;
|
||||
int _buflen;
|
||||
int _size;
|
||||
int _start;
|
||||
int _stop;
|
||||
|
||||
public:
|
||||
explicit CircleBuf(int l);
|
||||
~CircleBuf();
|
||||
public:
|
||||
explicit CircleBuf(int l);
|
||||
~CircleBuf();
|
||||
|
||||
bool empty() { return size == 0; }
|
||||
void dump();
|
||||
void flush();
|
||||
void read(char *b, int len);
|
||||
void read(int fd, int len);
|
||||
void read(int fd);
|
||||
void readall(int fd);
|
||||
void write(char b);
|
||||
void write(const char *b);
|
||||
void write(const char *b, int len);
|
||||
bool empty() const { return _size == 0; }
|
||||
int size() const { return _size; }
|
||||
void dump();
|
||||
void flush();
|
||||
void read(char *b, int len);
|
||||
void read(int fd, int len);
|
||||
void read(int fd);
|
||||
void read(std::ostream &out);
|
||||
void readall(int fd);
|
||||
void write(char b);
|
||||
void write(const char *b);
|
||||
void write(const char *b, int len);
|
||||
};
|
||||
|
||||
#endif // __CIRCLEBUF_HH__
|
||||
|
|
|
@ -73,6 +73,9 @@ SimConsole::Event::process(int revent)
|
|||
SimConsole::SimConsole(const string &name, const string &file, int num)
|
||||
: SimObject(name), event(NULL), number(num), in_fd(-1), out_fd(-1),
|
||||
listener(NULL), txbuf(16384), rxbuf(16384), outfile(NULL),
|
||||
#if TRACING_ON == 1
|
||||
linebuf(16384),
|
||||
#endif
|
||||
_status(0), _enable(0), intr(NULL)
|
||||
{
|
||||
if (!file.empty())
|
||||
|
@ -231,7 +234,7 @@ SimConsole::in()
|
|||
char c;
|
||||
rxbuf.read(&c, 1);
|
||||
|
||||
DPRINTF(Console, "in: \'%c\' %#02x status: %#x\n",
|
||||
DPRINTF(ConsoleVerbose, "in: \'%c\' %#02x status: %#x\n",
|
||||
isprint(c) ? c : ' ', c, _status);
|
||||
|
||||
return c;
|
||||
|
@ -240,6 +243,28 @@ SimConsole::in()
|
|||
void
|
||||
SimConsole::out(char c, bool raise_int)
|
||||
{
|
||||
#if TRACING_ON == 1
|
||||
if (DTRACE(Console)) {
|
||||
static char last = '\0';
|
||||
|
||||
if (c != '\n' && c != '\r' ||
|
||||
last != '\n' && last != '\r') {
|
||||
if (c == '\n' || c == '\r') {
|
||||
int size = linebuf.size();
|
||||
char *buffer = new char[size + 1];
|
||||
linebuf.read(buffer, size);
|
||||
buffer[size] = '\0';
|
||||
DPRINTF(Console, "%s\n", buffer);
|
||||
delete [] buffer;
|
||||
} else {
|
||||
linebuf.write(c);
|
||||
}
|
||||
}
|
||||
|
||||
last = c;
|
||||
}
|
||||
#endif
|
||||
|
||||
txbuf.write(c);
|
||||
|
||||
if (out_fd >= 0)
|
||||
|
@ -251,13 +276,13 @@ SimConsole::out(char c, bool raise_int)
|
|||
if (raise_int)
|
||||
raiseInt(TransmitInterrupt);
|
||||
|
||||
DPRINTF(Console, "out: \'%c\' %#02x",
|
||||
DPRINTF(ConsoleVerbose, "out: \'%c\' %#02x",
|
||||
isprint(c) ? c : ' ', (int)c);
|
||||
|
||||
if (raise_int)
|
||||
DPRINTF(Console, "status: %#x\n", _status);
|
||||
DPRINTF(ConsoleVerbose, "status: %#x\n", _status);
|
||||
else
|
||||
DPRINTF(Console, "\n");
|
||||
DPRINTF(ConsoleVerbose, "\n");
|
||||
}
|
||||
|
||||
inline bool
|
||||
|
@ -329,6 +354,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimConsole)
|
|||
SimObjectParam<ConsoleListener *> listener;
|
||||
SimObjectParam<IntrControl *> intr_control;
|
||||
Param<string> output;
|
||||
Param<bool> append_name;
|
||||
Param<int> number;
|
||||
|
||||
END_DECLARE_SIM_OBJECT_PARAMS(SimConsole)
|
||||
|
@ -338,13 +364,17 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(SimConsole)
|
|||
INIT_PARAM(listener, "console listener"),
|
||||
INIT_PARAM(intr_control, "interrupt controller"),
|
||||
INIT_PARAM_DFLT(output, "file to dump output to", ""),
|
||||
INIT_PARAM_DFLT(append_name, "append name() to filename", true),
|
||||
INIT_PARAM_DFLT(number, "console number", 0)
|
||||
|
||||
END_INIT_SIM_OBJECT_PARAMS(SimConsole)
|
||||
|
||||
CREATE_SIM_OBJECT(SimConsole)
|
||||
{
|
||||
SimConsole *console = new SimConsole(getInstanceName(), output, number);
|
||||
string filename = output;
|
||||
if (!filename.empty() && append_name)
|
||||
filename += "." + getInstanceName();
|
||||
SimConsole *console = new SimConsole(getInstanceName(), filename, number);
|
||||
((ConsoleListener *)listener)->add(console);
|
||||
((SimConsole *)console)->initInt(intr_control);
|
||||
((SimConsole *)console)->setInt(SimConsole::TransmitInterrupt |
|
||||
|
@ -383,12 +413,14 @@ void
|
|||
ConsoleListener::listen(int port)
|
||||
{
|
||||
while (!listener.listen(port, true)) {
|
||||
DPRINTF(Console, ": can't bind address console port %d inuse PID %d\n",
|
||||
DPRINTF(Console,
|
||||
": can't bind address console port %d inuse PID %d\n",
|
||||
port, getpid());
|
||||
port++;
|
||||
}
|
||||
|
||||
cerr << "Listening for console connection on port " << port << endl;
|
||||
ccprintf(cerr, "Listening for console connection on port %d\n", port);
|
||||
|
||||
event = new Event(this, listener.getfd(), POLLIN);
|
||||
pollQueue.schedule(event);
|
||||
}
|
||||
|
@ -401,8 +433,7 @@ void
|
|||
ConsoleListener::accept()
|
||||
{
|
||||
if (!listener.islistening())
|
||||
panic("%s: cannot accept a connection if we're not listening!",
|
||||
name());
|
||||
panic("%s: cannot accept a connection if not listening!", name());
|
||||
|
||||
int sfd = listener.accept(true);
|
||||
if (sfd != -1) {
|
||||
|
|
|
@ -74,6 +74,9 @@ class SimConsole : public SimObject
|
|||
CircleBuf txbuf;
|
||||
CircleBuf rxbuf;
|
||||
std::ostream *outfile;
|
||||
#if TRACING_ON == 1
|
||||
CircleBuf linebuf;
|
||||
#endif
|
||||
|
||||
public:
|
||||
///////////////////////
|
||||
|
|
Loading…
Reference in a new issue