Hi James,

Yes, I ran into this last fall and fixed it in our local tree (though unfortunately after the 1.1 release). So it's FITNR. Here's my patch to tide you over until then.

Steve

James Srinivasan wrote:
I've recently noticed that file descriptors in m5's syscall emulation
mode aren't reused where I think they may be able to. Process::open_fd
(called by openFunc) iterates over the fd_map array looking for a free
fd; however, closeFunc does not change the respective array entry when
the file is closed. If MAX_FD is large enough, this doesn't usually
cause any problems but I have run into one SPEC2000 benchmark (wupwise)
in which this isn't the case. Off the top of my head, adding
Process::close_fd which sets the array entry to -1 and calling it
from closeFunc ought to work.

James

diff -Nru a/sim/process.cc b/sim/process.cc
--- a/sim/process.cc    2006-05-18 07:24:58 -04:00
+++ b/sim/process.cc    2006-05-18 07:24:58 -04:00
@@ -194,23 +194,32 @@
 
 // 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!");
+}
+
+
+// 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);
 
-    return free_fd;
+    fd_map[tgt_fd] = -1;
 }
 
 
diff -Nru a/sim/process.hh b/sim/process.hh
--- a/sim/process.hh    2006-05-18 07:24:58 -04:00
+++ b/sim/process.hh    2006-05-18 07:24:58 -04:00
@@ -127,7 +127,7 @@
 
   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:
@@ -149,7 +149,10 @@
     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 -Nru a/sim/syscall_emul.cc b/sim/syscall_emul.cc
--- a/sim/syscall_emul.cc       2006-05-18 07:24:58 -04:00
+++ b/sim/syscall_emul.cc       2006-05-18 07:24:58 -04:00
@@ -113,8 +113,11 @@
 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 -Nru a/sim/syscall_emul.hh b/sim/syscall_emul.hh
--- a/sim/syscall_emul.hh       2006-05-18 07:24:58 -04:00
+++ b/sim/syscall_emul.hh       2006-05-18 07:24:58 -04:00
@@ -342,7 +342,7 @@
     // 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);
 }
 
 

Reply via email to