From 4410876773fa076a2b197cfbaf23ceea73137397 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Thu, 10 Nov 2005 21:08:33 -0500 Subject: [PATCH] Actually free Process fd_map entries when a file is closed... amazingly we never did that before. Caused us to run out of file descriptors in twolf. sim/process.cc: Add free_fd() method to free closed target fd in simulator fd map. Rename open_fd() to alloc_fd() for symmetry with free_fd(). sim/process.hh: Add free_fd() method to free closed target fd in simulator fd map. Rename open_fd() to alloc_fd() for symmetry with free_fd(). Crank up MAX_FD while we're at it. sim/syscall_emul.cc: Call free_fd() on process when target closes a file. sim/syscall_emul.hh: Process open_fd() renamed to alloc_fd(). --HG-- extra : convert_revision : d780f4ccfd5a0989230b0afbdbd276212b87550c --- sim/process.cc | 25 +++++++++++++++++-------- sim/process.hh | 7 +++++-- sim/syscall_emul.cc | 7 +++++-- sim/syscall_emul.hh | 2 +- 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/sim/process.cc b/sim/process.cc index b04582233..a6cf5ded7 100644 --- a/sim/process.cc +++ b/sim/process.cc @@ -191,23 +191,32 @@ Process::dup_fd(int sim_fd, int tgt_fd) // generate new target fd for sim_fd int -Process::open_fd(int sim_fd) +Process::alloc_fd(int sim_fd) { - int free_fd; - // in case open() returns an error, don't allocate a new fd if (sim_fd == -1) return -1; // find first free target fd - for (free_fd = 0; fd_map[free_fd] >= 0; ++free_fd) { - if (free_fd == MAX_FD) - panic("Process::open_fd: out of file descriptors!"); + for (int free_fd = 0; free_fd < MAX_FD; ++free_fd) { + if (fd_map[free_fd] == -1) { + fd_map[free_fd] = sim_fd; + return free_fd; + } } - fd_map[free_fd] = sim_fd; + panic("Process::alloc_fd: out of file descriptors!"); +} - return free_fd; + +// free target fd (e.g., after close) +void +Process::free_fd(int tgt_fd) +{ + if (fd_map[tgt_fd] == -1) + warn("Process::free_fd: request to free unused fd %d", tgt_fd); + + fd_map[tgt_fd] = -1; } diff --git a/sim/process.hh b/sim/process.hh index 28c16a444..2116ef632 100644 --- a/sim/process.hh +++ b/sim/process.hh @@ -124,7 +124,7 @@ class Process : public SimObject private: // file descriptor remapping support - static const int MAX_FD = 100; // max legal fd value + static const int MAX_FD = 256; // max legal fd value int fd_map[MAX_FD+1]; public: @@ -146,7 +146,10 @@ class Process : public SimObject void dup_fd(int sim_fd, int tgt_fd); // generate new target fd for sim_fd - int open_fd(int sim_fd); + int alloc_fd(int sim_fd); + + // free target fd (e.g., after close) + void free_fd(int tgt_fd); // look up simulator fd for given target fd int sim_fd(int tgt_fd); diff --git a/sim/syscall_emul.cc b/sim/syscall_emul.cc index 4ae2d2631..50650018e 100644 --- a/sim/syscall_emul.cc +++ b/sim/syscall_emul.cc @@ -110,8 +110,11 @@ obreakFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) SyscallReturn closeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) { - int fd = p->sim_fd(xc->getSyscallArg(0)); - return close(fd); + int target_fd = xc->getSyscallArg(0); + int status = close(p->sim_fd(target_fd)); + if (status >= 0) + p->free_fd(target_fd); + return status; } diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh index 17889113e..f22b6dcb7 100644 --- a/sim/syscall_emul.hh +++ b/sim/syscall_emul.hh @@ -339,7 +339,7 @@ openFunc(SyscallDesc *desc, int callnum, Process *process, // open the file int fd = open(path.c_str(), hostFlags, mode); - return (fd == -1) ? -errno : process->open_fd(fd); + return (fd == -1) ? -errno : process->alloc_fd(fd); }