aboutsummaryrefslogtreecommitdiff
path: root/rt/aio_misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'rt/aio_misc.c')
-rw-r--r--rt/aio_misc.c98
1 files changed, 46 insertions, 52 deletions
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);