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