about summary refs log tree commit diff
path: root/rt
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2000-08-12 05:14:52 +0000
committerUlrich Drepper <drepper@redhat.com>2000-08-12 05:14:52 +0000
commit56ddf355daf2f9812b9560ca9fa698520b7000f8 (patch)
treec6dee26e06b0e0d8d0b07e14bc20eeb64650b5b4 /rt
parent1a5b42af05ea744cbba2cafe2ea40b2ed399cd0b (diff)
downloadglibc-56ddf355daf2f9812b9560ca9fa698520b7000f8.tar.gz
glibc-56ddf355daf2f9812b9560ca9fa698520b7000f8.tar.xz
glibc-56ddf355daf2f9812b9560ca9fa698520b7000f8.zip
Update.
2000-08-11  Ulrich Drepper  <drepper@redhat.com>

	* 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  <jakub@redhat.com>

	* 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.
Diffstat (limited to 'rt')
-rw-r--r--rt/aio_cancel.c24
-rw-r--r--rt/aio_misc.c98
-rw-r--r--rt/aio_misc.h3
3 files changed, 65 insertions, 60 deletions
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 <assert.h>
 #include <errno.h>
 
 #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
 };