From 56ddf355daf2f9812b9560ca9fa698520b7000f8 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sat, 12 Aug 2000 05:14:52 +0000 Subject: Update. 2000-08-11 Ulrich Drepper * rt/aio_cancel.c: If canceling a specific request which is running *really* do nothing. * rt/aio_misc.h: Add `done' to states of a request. * rt/aio_misc.c: Add several tests for the correct state. Simplify request table memory handling. 2000-08-10 Jakub Jelinek * dirent/scandir.c: Use it for scandir64 and old_scandir64 as well. * dirent/scandir64.c: Move... * sysdeps/generic/scandir64.c: ...here. * dirent/alphasort64.c: Move... * sysdeps/generic/alphasort64.c: ...here. * dirent/versionsort64.c: Move... * sysdeps/generic/versionsort64.c: ...here. * sysdeps/unix/sysv/linux/i386/dirent/Versions (alphasort64, getdirentries64, readdir64, readdir64_r, scandir64, versionsort64): Export symbols at GLIBC_2.2. * sysdeps/unix/sysv/linux/powerpc/dirent/Versions: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/dirent/Versions: Likewise. * include/dirent.h (__readdir64_r, __scandir64, __alphasort64, __versionsort64): Add prototypes. * io/Versions (__xstat64, __fxstat64, __lxstat64): Export at GLIBC_2.2. * sysdeps/unix/sysv/linux/alpha/kernel_stat.h (__xstat_conv): Remove unused prototype. * sysdeps/unix/sysv/linux/alpha/readdir.c: Export at both GLIBC_2.1 and GLIBC_2.2. * sysdeps/unix/sysv/linux/alpha/readdir_r.c: Likewise. * sysdeps/unix/sysv/linux/alpha/getdents.c: New. * sysdeps/unix/sysv/linux/alpha/getdents64.c: New. * sysdeps/unix/sysv/linux/bits/types.h (__ino64_t): Change to __u_quad_t. * sysdeps/unix/sysv/linux/bits/stat.h (struct stat, struct stat64): Adjust for kernel-2.4.0-test6 layout. * sysdeps/unix/sysv/linux/i386/fxstat.c (__fxstat64): Export at both GLIBC_2.1 and GLIBC_2.2. * sysdeps/unix/sysv/linux/i386/lxstat.c (__lxstat64): Likewise. * sysdeps/unix/sysv/linux/i386/xstat.c (__xstat64): Likewise. * sysdeps/unix/sysv/linux/i386/getdents64.c: New. * sysdeps/unix/sysv/linux/i386/olddirent.h: New. * sysdeps/unix/sysv/linux/i386/readdir64.c: New. * sysdeps/unix/sysv/linux/i386/readdir64_r.c: New. * sysdeps/unix/sysv/linux/i386/scandir64.c: New. * sysdeps/unix/sysv/linux/i386/alphasort64.c: New. * sysdeps/unix/sysv/linux/i386/versionsort64.c: New. * sysdeps/unix/sysv/linux/ia64/getdents.c: New. * sysdeps/unix/sysv/linux/ia64/getdents64.c: New. * sysdeps/unix/sysv/linux/ia64/readdir.c: Include alpha/readdir.c. * sysdeps/unix/sysv/linux/ia64/readdir_r.c: Include alpha/readdir_r.c. * sysdeps/unix/sysv/linux/mips/bits/types.h (__ino64_t): Change to __u_quad_t. * sysdeps/unix/sysv/linux/powerpc/bits/stat.h: New. * sysdeps/unix/sysv/linux/powerpc/kernel_stat.h (_HAVE_STAT*): Define. * sysdeps/unix/sysv/linux/powerpc/scandir64.c: New. * sysdeps/unix/sysv/linux/powerpc/getdents64.c: New. * sysdeps/unix/sysv/linux/powerpc/readdir64.c: New. * sysdeps/unix/sysv/linux/powerpc/readdir64_r.c: New. * sysdeps/unix/sysv/linux/sparc/bits/types.h (__ino64_t): Change to __u_quad_t. * sysdeps/unix/sysv/linux/sparc/bits/stat.h: New. * sysdeps/unix/sysv/linux/sparc/sparc32/kernel_stat.h (_HAVE_STAT*): Define. * sysdeps/unix/sysv/linux/sparc/sparc32/getdents64.c: New. * sysdeps/unix/sysv/linux/sparc/sparc32/readdir64.c: New. * sysdeps/unix/sysv/linux/sparc/sparc32/readdir64_r.c: New. * sysdeps/unix/sysv/linux/sparc/sparc32/scandir64.c: New. * sysdeps/unix/sysv/linux/sparc/sparc64/kernel_stat.h (_HAVE_STAT*): Define. * sysdeps/unix/sysv/linux/sparc/sparc64/readdir.c: Include alpha/readdir.c. * sysdeps/unix/sysv/linux/sparc/sparc64/readdir_r.c: Include alpha/readdir_r.c * sysdeps/unix/sysv/linux/sparc/sparc64/getdents.c: New. * sysdeps/unix/sysv/linux/sparc/sparc64/getdents64.c: New. * sysdeps/unix/sysv/linux/fxstat64.c (__fxstat64): If _HAVE_STAT64___ST_INO and __st_ino != (uint32_t)st_ino, set st_ino from __st_ino. * sysdeps/unix/sysv/linux/lxstat64.c (__lxstat64): Likewise. * sysdeps/unix/sysv/linux/xstat64.c (__xstat64): Likewise. * sysdeps/unix/sysv/linux/xstatconv.c (xstat_conv, xstat64_conv, xstat32_conv): Use _HAVE_STAT* macros. If _HAVE_STAT64___ST_INO, set __st_ino in addition to st_ino. * sysdeps/unix/sysv/linux/kernel_stat.h (_HAVE_STAT*): Define. * sysdeps/unix/sysv/linux/getdents.c: Use it for __getdents64 and __old_getdents64 as well. * sysdeps/unix/sysv/linux/getdirentries.c: Use it for getdirentries64 and old_getdirentries64 as well. * sysdeps/unix/sysv/linux/getdirentries64.c (GETDIRENTRIES, __GETDENTS): Define. (GETDENTS64): Remove. * sysdeps/unix/sysv/linux/getdents64.c (__GETDENTS, DIRENT_TYPE): Define. (GETDENTS64): Remove. * sysdeps/unix/sysv/linux/readdir64.c: Use sysdeps/unix/readdir.c. * sysdeps/unix/sysv/linux/readdir64_r.c: Use sysdeps/unix/readdir_r.c. * sysdeps/unix/readdir.c: Use it for readdir64 and __old_readdir64 as well. * sysdeps/unix/readdir_r.c: Use it for readdir64_r and __old_readdir64_r as well. * sysdeps/unix/sysv/linux/kernel-features.h: Define __ASSUME_ST_INO_64_bit for kernel 2.4.1 and up. * sysdeps/unix/sysv/linux/ia64/bits/siginfo.h: Add SI_KERNEL define. --- rt/aio_cancel.c | 24 +++++++++----- rt/aio_misc.c | 98 +++++++++++++++++++++++++++------------------------------ rt/aio_misc.h | 3 +- 3 files changed, 65 insertions(+), 60 deletions(-) (limited to 'rt') diff --git a/rt/aio_cancel.c b/rt/aio_cancel.c index 48e647a263..c1cfea50c8 100644 --- a/rt/aio_cancel.c +++ b/rt/aio_cancel.c @@ -29,6 +29,7 @@ /* And undo the hack. */ #undef aio_cancel64 +#include #include #include "aio_misc.h" @@ -74,16 +75,19 @@ aio_cancel (fildes, aiocbp) /* Don't remove the entry if a thread is already working on it. */ if (req->running == allocated) - result = AIO_NOTCANCELED; - else if (req->running == yes) + { + result = AIO_NOTCANCELED; + req = NULL; + } + else { /* We can remove the entry. */ __aio_remove_request (last, req, 0); result = AIO_CANCELED; - } - req->next_prio = NULL; + req->next_prio = NULL; + } } } else @@ -103,12 +107,17 @@ aio_cancel (fildes, aiocbp) old->next_prio = NULL; result = AIO_NOTCANCELED; + + if (req != NULL) + __aio_remove_request (old, req, 1); } else - result = AIO_CANCELED; + { + result = AIO_CANCELED; - /* We can remove the entry. */ - __aio_remove_request (NULL, req, 1); + /* We can remove the entry. */ + __aio_remove_request (NULL, req, 1); + } } } @@ -116,6 +125,7 @@ aio_cancel (fildes, aiocbp) while (req != NULL) { struct requestlist *old = req; + assert (req->running == yes || req->running == queued); req->aiocbp->aiocb.__error_code = ECANCELED; req->aiocbp->aiocb.__return_value = -1; __aio_notify (req); diff --git a/rt/aio_misc.c b/rt/aio_misc.c index af3e90f881..b26558ac39 100644 --- a/rt/aio_misc.c +++ b/rt/aio_misc.c @@ -36,16 +36,16 @@ static void add_request_to_runlist (struct requestlist *newrequest); static struct requestlist **pool; /* Number of total and allocated pool entries. */ -static size_t pool_tab_size; +static size_t pool_max_size; static size_t pool_size; /* We implement a two dimensional array but allocate each row separately. The macro below determines how many entries should be used per row. It should better be a power of two. */ -#define ENTRIES_PER_ROW 16 +#define ENTRIES_PER_ROW 32 -/* The row table is incremented in units of this. */ -#define ROW_STEP 8 +/* How many rows we allocate at once. */ +#define ROWS_STEP 8 /* List of available entries. */ static struct requestlist *freelist; @@ -68,7 +68,7 @@ static int idle_thread_count; static struct aioinit optim = { 20, /* int aio_threads; Maximal number of threads. */ - 256, /* int aio_num; Number of expected simultanious requests. */ + 64, /* int aio_num; Number of expected simultanious requests. */ 0, 0, 0, @@ -96,51 +96,33 @@ get_elem (void) if (freelist == NULL) { struct requestlist *new_row; - size_t new_size; + int cnt; assert (sizeof (struct aiocb) == sizeof (struct aiocb64)); - /* Compute new size. */ - new_size = pool_size ? pool_size + ENTRIES_PER_ROW : optim.aio_num; - - if ((new_size / ENTRIES_PER_ROW) >= pool_tab_size) + if (pool_size + 1 >= pool_max_size) { - size_t new_tab_size = new_size / ENTRIES_PER_ROW; + size_t new_max_size = pool_max_size + ROWS_STEP; struct requestlist **new_tab; new_tab = (struct requestlist **) - realloc (pool, (new_tab_size * sizeof (struct requestlist *))); + realloc (pool, new_max_size * sizeof (struct requestlist *)); if (new_tab == NULL) return NULL; - pool_tab_size = new_tab_size; + pool_max_size = new_max_size; pool = new_tab; } - if (pool_size == 0) - { - size_t cnt; - - new_row = (struct requestlist *) - calloc (new_size, sizeof (struct requestlist)); - - if (new_row == NULL) - return NULL; + /* Allocat the new row. */ + cnt = pool_size == 0 ? optim.aio_num : ENTRIES_PER_ROW; + new_row = (struct requestlist *) calloc (cnt, + sizeof (struct requestlist)); + if (new_row == NULL) + return NULL; - for (cnt = 0; cnt < new_size / ENTRIES_PER_ROW; ++cnt) - pool[cnt] = &new_row[cnt * ENTRIES_PER_ROW]; - } - else - { - /* Allocat one new row. */ - new_row = (struct requestlist *) - calloc (ENTRIES_PER_ROW, sizeof (struct requestlist)); - if (new_row == NULL) - return NULL; - - pool[new_size / ENTRIES_PER_ROW - 1] = new_row; - } + pool[pool_size++] = new_row; /* Put all the new entries in the freelist. */ do @@ -148,7 +130,7 @@ get_elem (void) new_row->next_prio = freelist; freelist = new_row++; } - while (++pool_size < new_size); + while (--cnt > 0); } result = freelist; @@ -210,8 +192,11 @@ internal_function __aio_remove_request (struct requestlist *last, struct requestlist *req, int all) { + assert (req->running == yes || req->running == queued + || req->running == done); + if (last != NULL) - last->next_prio = req->next_prio; + last->next_prio = all ? NULL : req->next_prio; else { if (all || req->next_prio == NULL) @@ -419,20 +404,25 @@ __aio_enqueue_request (aiocb_union *aiocbp, int operation) pthread_attr_init (&attr); pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); + running = newp->running = allocated; + /* Now try to start a thread. */ if (pthread_create (&thid, &attr, handle_fildes_io, newp) == 0) + /* We managed to enqueue the request. All errors which can + happen now can be recognized by calls to `aio_return' and + `aio_error'. */ + ++nthreads; + else { - /* We managed to enqueue the request. All errors which can - happen now can be recognized by calls to `aio_return' and - `aio_error'. */ - running = allocated; - ++nthreads; + /* Reset the running flat. The new request is not running. */ + running = newp->running = yes; + + if (nthreads == 0) + /* We cannot create a thread in the moment and there is + also no thread running. This is a problem. `errno' is + set to EAGAIN if this is only a temporary problem. */ + result = -1; } - else if (nthreads == 0) - /* We cannot create a thread in the moment and there is - also no thread running. This is a problem. `errno' is - set to EAGAIN if this is only a temporary problem. */ - result = -1; } } @@ -486,6 +476,9 @@ handle_fildes_io (void *arg) pthread_mutex_lock (&__aio_requests_mutex); else { + /* Hopefully this request is marked as running. */ + assert (runp->running == allocated); + /* Update our variables. */ aiocbp = runp->aiocbp; fildes = aiocbp->aiocb.aio_fildes; @@ -584,6 +577,11 @@ handle_fildes_io (void *arg) request. */ __aio_notify (runp); + /* For debugging purposes we reset the running flag of the + finished request. */ + assert (runp->running == allocated); + runp->running = done; + /* Now dequeue the current request. */ __aio_remove_request (NULL, runp, 0); if (runp->next_prio != NULL) @@ -672,11 +670,7 @@ free_res (void) { size_t row; - /* The first block of rows as specified in OPTIM is allocated in - one chunk. */ - free (pool[0]); - - for (row = optim.aio_num / ENTRIES_PER_ROW; row < pool_tab_size; ++row) + for (row = 0; row < pool_max_size; ++row) free (pool[row]); free (pool); diff --git a/rt/aio_misc.h b/rt/aio_misc.h index eda06541e6..372b5556ca 100644 --- a/rt/aio_misc.h +++ b/rt/aio_misc.h @@ -62,7 +62,8 @@ enum no, queued, yes, - allocated + allocated, + done }; -- cgit v1.2.3