I started a cleanup of libc to make it thread-safe.  I would
like to get rid of the hash table in libc/gen/telldir.c and
maintain telldir position information on a per-DIR basis.  A
summary of the changes are as follows:

  o Add a LIST_HEAD to DIR to contain a queue of telldir
    positions.  Also add a location count (used as the magic
    for telldir) to DIR.  A future change may also add a
    mutex/lock.

  o Remove the hash table from telldir.c.  Recode to use
    queue macros.

  o Remove 'const' from 'telldir(const DIR *)'.

  o Remove 'register' variables as suggested in another
    recent thread.

Question: Is there a reason to use a hash table in each DIR
instead of a list (for performance reasons)?

Proposed diffs below.

-- 
Dan Eischen

Index: dirent.h
===================================================================
RCS file: /opt/FreeBSD/cvs/src/include/dirent.h,v
retrieving revision 1.7
diff -u -r1.7 dirent.h
--- dirent.h    1999/12/29 05:01:20     1.7
+++ dirent.h    2000/12/04 20:03:49
@@ -46,12 +46,15 @@
 #ifdef _POSIX_SOURCE
 typedef void * DIR;
 #else
+#include <sys/queue.h>
 
 #define        d_ino           d_fileno        /* backward compatibility */
 
 /* definitions for library routines operating on directories. */
 #define        DIRBLKSIZ       1024
 
+struct ddloc;
+
 /* structure describing an open directory. */
 typedef struct _dirdesc {
        int     dd_fd;          /* file descriptor associated with directory */
@@ -61,7 +64,9 @@
        int     dd_len;         /* size of data buffer */
        long    dd_seek;        /* magic cookie returned by getdirentries */
        long    dd_rewind;      /* magic cookie for rewinding */
-       int     dd_flags;       /* flags for readdir */
+       int     dd_flags;       /* flags for readdir */\
+       long    dd_loccnt;      /* current key for dd_locq entry */
+       LIST_HEAD(, ddloc) dd_locq; /* telldir position recording */
 } DIR;
 
 #define        dirfd(dirp)     ((dirp)->dd_fd)
@@ -89,7 +94,7 @@
 int closedir __P((DIR *));
 #ifndef _POSIX_SOURCE
 DIR *__opendir2 __P((const char *, int));
-long telldir __P((const DIR *));
+long telldir __P((DIR *));
 void seekdir __P((DIR *, long));
 int scandir __P((const char *, struct dirent ***,
     int (*)(struct dirent *), int (*)(const void *, const void *)));
Index: libc/gen/closedir.c
===================================================================
RCS file: /opt/FreeBSD/cvs/src/lib/libc/gen/closedir.c,v
retrieving revision 1.6
diff -u -r1.6 closedir.c
--- libc/gen/closedir.c 2000/01/27 23:06:14     1.6
+++ libc/gen/closedir.c 2000/12/04 20:03:30
@@ -58,7 +58,7 @@
        dirp->dd_fd = -1;
        dirp->dd_loc = 0;
        free((void *)dirp->dd_buf);
-       free((void *)dirp);
        _reclaim_telldir(dirp);
+       free((void *)dirp);
        return(_close(fd));
 }
Index: libc/gen/opendir.c
===================================================================
RCS file: /opt/FreeBSD/cvs/src/lib/libc/gen/opendir.c,v
retrieving revision 1.10
diff -u -r1.10 opendir.c
--- libc/gen/opendir.c  2000/01/27 23:06:18     1.10
+++ libc/gen/opendir.c  2000/12/04 20:03:13
@@ -259,6 +259,8 @@
        dirp->dd_loc = 0;
        dirp->dd_fd = fd;
        dirp->dd_flags = flags;
+       dirp->dd_loccnt = 0;
+       LIST_INIT(&dirp->dd_locq);
 
        /*
         * Set up seek point for rewinddir.
Index: libc/gen/telldir.c
===================================================================
RCS file: /opt/FreeBSD/cvs/src/lib/libc/gen/telldir.c,v
retrieving revision 1.4
diff -u -r1.4 telldir.c
--- libc/gen/telldir.c  1995/05/30 05:40:26     1.4
+++ libc/gen/telldir.c  2000/12/04 20:18:22
@@ -54,39 +54,28 @@
  * associated with that return value.
  */
 struct ddloc {
-       struct  ddloc *loc_next;/* next structure in list */
+       LIST_ENTRY(ddloc) loc_lqe; /* list entry */
        long    loc_index;      /* key associated with structure */
        long    loc_seek;       /* magic cookie returned by getdirentries */
        long    loc_loc;        /* offset of entry in buffer */
-       const DIR* loc_dirp;    /* directory which used this entry */
 };
 
-#define        NDIRHASH        32      /* Num of hash lists, must be a power of 2 */
-#define        LOCHASH(i)      ((i)&(NDIRHASH-1))
-
-static long    dd_loccnt;      /* Index of entry for sequential readdir's */
-static struct  ddloc *dd_hash[NDIRHASH];   /* Hash list heads for ddlocs */
-
 /*
  * return a pointer into a directory
  */
 long
 telldir(dirp)
-       const DIR *dirp;
+       DIR *dirp;
 {
-       register int index;
-       register struct ddloc *lp;
+       struct ddloc *lp;
 
        if ((lp = (struct ddloc *)malloc(sizeof(struct ddloc))) == NULL)
                return (-1);
-       index = dd_loccnt++;
-       lp->loc_index = index;
+       lp->loc_index = dirp->dd_loccnt++;
        lp->loc_seek = dirp->dd_seek;
        lp->loc_loc = dirp->dd_loc;
-       lp->loc_dirp = dirp;
-       lp->loc_next = dd_hash[LOCHASH(index)];
-       dd_hash[LOCHASH(index)] = lp;
-       return (index);
+       LIST_INSERT_HEAD(&dirp->dd_locq, lp, loc_lqe);
+       return (lp->loc_index);
 }
 
 /*
@@ -95,20 +84,15 @@
  */
 void
 _seekdir(dirp, loc)
-       register DIR *dirp;
+       DIR *dirp;
        long loc;
 {
-       register struct ddloc *lp;
-       register struct ddloc **prevlp;
+       struct ddloc *lp;
        struct dirent *dp;
 
-       prevlp = &dd_hash[LOCHASH(loc)];
-       lp = *prevlp;
-       while (lp != NULL) {
+       LIST_FOREACH(lp, &dirp->dd_locq, loc_lqe) {
                if (lp->loc_index == loc)
                        break;
-               prevlp = &lp->loc_next;
-               lp = lp->loc_next;
        }
        if (lp == NULL)
                return;
@@ -124,7 +108,7 @@
        }
 found:
 #ifdef SINGLEUSE
-       *prevlp = lp->loc_next;
+       LIST_REMOVE(lp, loc_lqe);
        free((caddr_t)lp);
 #endif
 }
@@ -134,24 +118,16 @@
  */
 void
 _reclaim_telldir(dirp)
-       register const DIR *dirp;
+       DIR *dirp;
 {
-       register struct ddloc *lp;
-       register struct ddloc **prevlp;
-       int i;
-
-       for (i = 0; i < NDIRHASH; i++) {
-               prevlp = &dd_hash[i];
-               lp = *prevlp;
-               while (lp != NULL) {
-                       if (lp->loc_dirp == dirp) {
-                               *prevlp = lp->loc_next;
-                               free((caddr_t)lp);
-                               lp = *prevlp;
-                               continue;
-                       }
-                       prevlp = &lp->loc_next;
-                       lp = lp->loc_next;
-               }
+       struct ddloc *lp;
+       struct ddloc *templp;
+
+       lp = LIST_FIRST(&dirp->dd_locq);
+       while (lp != NULL) {
+               templp = lp;
+               lp = LIST_NEXT(lp, loc_lqe);
+               free(templp);
        }
+       LIST_INIT(&dirp->dd_locq);
 }


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to