summaryrefslogtreecommitdiff
path: root/src/dirent
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2012-04-24 16:32:23 -0400
committerRich Felker <dalias@aerifal.cx>2012-04-24 16:32:23 -0400
commit4750cf4202c29a895639b89099a7bdbe9ae422b6 (patch)
treeb682c69140ada09d2c498a80e7d84865d4c51e60 /src/dirent
parente7655ed37bc9c2d79d921af4f287ee5cf2788661 (diff)
downloadmusl-4750cf4202c29a895639b89099a7bdbe9ae422b6.tar.gz
ditch the priority inheritance locks; use malloc's version of lock
i did some testing trying to switch malloc to use the new internal lock with priority inheritance, and my malloc contention test got 20-100 times slower. if priority inheritance futexes are this slow, it's simply too high a price to pay for avoiding priority inversion. maybe we can consider them somewhere down the road once the kernel folks get their act together on this (and perferably don't link it to glibc's inefficient lock API)... as such, i've switch __lock to use malloc's implementation of lightweight locks, and updated all the users of the code to use an array with a waiter count for their locks. this should give optimal performance in the vast majority of cases, and it's simple. malloc is still using its own internal copy of the lock code because it seems to yield measurably better performance with -O3 when it's inlined (20% or more difference in the contention stress test).
Diffstat (limited to 'src/dirent')
-rw-r--r--src/dirent/__dirent.h2
-rw-r--r--src/dirent/readdir.c5
-rw-r--r--src/dirent/readdir_r.c6
-rw-r--r--src/dirent/rewinddir.c4
-rw-r--r--src/dirent/seekdir.c4
5 files changed, 9 insertions, 12 deletions
diff --git a/src/dirent/__dirent.h b/src/dirent/__dirent.h
index 07b3ee68..38a27b06 100644
--- a/src/dirent/__dirent.h
+++ b/src/dirent/__dirent.h
@@ -1,9 +1,9 @@
struct __DIR_s
{
- int lock;
int fd;
off_t tell;
int buf_pos;
int buf_end;
+ int lock[2];
char buf[2048];
};
diff --git a/src/dirent/readdir.c b/src/dirent/readdir.c
index 1aeb25a5..2d27d29a 100644
--- a/src/dirent/readdir.c
+++ b/src/dirent/readdir.c
@@ -16,10 +16,7 @@ struct dirent *readdir(DIR *dir)
if (dir->buf_pos >= dir->buf_end) {
int len = __getdents(dir->fd, (void *)dir->buf, sizeof dir->buf);
- if (len < 0) {
- dir->lock = 0;
- return NULL;
- } else if (len == 0) return 0;
+ if (len <= 0) return 0;
dir->buf_end = len;
dir->buf_pos = 0;
}
diff --git a/src/dirent/readdir_r.c b/src/dirent/readdir_r.c
index 58f60325..d3d7c608 100644
--- a/src/dirent/readdir_r.c
+++ b/src/dirent/readdir_r.c
@@ -11,18 +11,18 @@ int readdir_r(DIR *dir, struct dirent *buf, struct dirent **result)
int errno_save = errno;
int ret;
- LOCK(&dir->lock);
+ LOCK(dir->lock);
errno = 0;
de = readdir(dir);
if ((ret = errno)) {
- UNLOCK(&dir->lock);
+ UNLOCK(dir->lock);
return ret;
}
errno = errno_save;
if (de) memcpy(buf, de, de->d_reclen);
else buf = NULL;
- UNLOCK(&dir->lock);
+ UNLOCK(dir->lock);
*result = buf;
return 0;
}
diff --git a/src/dirent/rewinddir.c b/src/dirent/rewinddir.c
index c6138f7c..f2053008 100644
--- a/src/dirent/rewinddir.c
+++ b/src/dirent/rewinddir.c
@@ -5,9 +5,9 @@
void rewinddir(DIR *dir)
{
- LOCK(&dir->lock);
+ LOCK(dir->lock);
lseek(dir->fd, 0, SEEK_SET);
dir->buf_pos = dir->buf_end = 0;
dir->tell = 0;
- UNLOCK(&dir->lock);
+ UNLOCK(dir->lock);
}
diff --git a/src/dirent/seekdir.c b/src/dirent/seekdir.c
index 81a0e331..5be47d4a 100644
--- a/src/dirent/seekdir.c
+++ b/src/dirent/seekdir.c
@@ -5,8 +5,8 @@
void seekdir(DIR *dir, long off)
{
- LOCK(&dir->lock);
+ LOCK(dir->lock);
dir->tell = lseek(dir->fd, off, SEEK_SET);
dir->buf_pos = dir->buf_end = 0;
- UNLOCK(&dir->lock);
+ UNLOCK(dir->lock);
}