1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-01 10:06:57 +03:00
This commit is contained in:
Jakub Jelinek
2007-07-12 18:26:36 +00:00
parent 7d58530341
commit 0ecb606cb6
6215 changed files with 494638 additions and 305010 deletions

5
sysdeps/pthread/Versions Normal file
View File

@ -0,0 +1,5 @@
librt {
GLIBC_2.4 {
lio_listio; lio_listio64;
}
}

View File

@ -1,5 +1,5 @@
/* Cancel requests associated with given file descriptor.
Copyright (C) 1997, 1998, 2000, 2002 Free Software Foundation, Inc.
Copyright (C) 1997, 1998, 2000, 2002, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@ -34,7 +34,7 @@
#include <assert.h>
#include <errno.h>
#include "aio_misc.h"
#include <aio_misc.h>
int

View File

@ -1,5 +1,5 @@
/* Synchronize I/O in given file descriptor.
Copyright (C) 1997, 1999, 2002 Free Software Foundation, Inc.
Copyright (C) 1997, 1999, 2002, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@ -30,7 +30,7 @@
#undef aio_fsync64
#include <errno.h>
#include "aio_misc.h"
#include <aio_misc.h>
int

View File

@ -1,5 +1,5 @@
/* Handle general operations.
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2006
Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@ -46,8 +46,7 @@ __aio_create_helper_thread (pthread_t *threadp, void *(*tf) (void *), void *arg)
(void) pthread_attr_destroy (&attr);
return ret;
}
}
#endif
static void add_request_to_runlist (struct requestlist *newrequest);

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
/* Copyright (C) 1997,1999,2000,2001,2003,2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -46,7 +46,12 @@ struct waitlist
{
struct waitlist *next;
/* The next two fields is used in synchronous `lio_listio' operations. */
#ifndef DONT_NEED_AIO_MISC_COND
pthread_cond_t *cond;
#endif
int *result;
volatile int *counterp;
/* The next field is used in asynchronous `lio_listio' operations. */
struct sigevent *sigevp;

View File

@ -1,6 +1,5 @@
/* Notify initiator of AIO request.
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004
Free Software Foundation, Inc.
Copyright (C) 1997-2001, 2003, 2004, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@ -144,15 +143,24 @@ __aio_notify (struct requestlist *req)
{
struct waitlist *next = waitlist->next;
/* Decrement the counter. This is used in both cases. */
--*waitlist->counterp;
if (waitlist->sigevp == NULL)
pthread_cond_signal (waitlist->cond);
{
if (waitlist->result != NULL && aiocbp->__return_value == -1)
*waitlist->result = -1;
#ifdef DONT_NEED_AIO_MISC_COND
AIO_MISC_NOTIFY (waitlist);
#else
/* Decrement the counter. */
--*waitlist->counterp;
pthread_cond_signal (waitlist->cond);
#endif
}
else
/* This is part of a asynchronous `lio_listio' operation. If
this request is the last one, send the signal. */
if (*waitlist->counterp == 0)
if (--*waitlist->counterp == 0)
{
#ifdef BROKEN_THREAD_SIGNALS
__aio_notify_only (waitlist->sigevp, waitlist->caller_pid);

View File

@ -1,5 +1,5 @@
/* Asynchronous read.
Copyright (C) 1997, 1999 Free Software Foundation, Inc.
Copyright (C) 1997, 1999, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@ -20,7 +20,7 @@
#include <aio.h>
#include "aio_misc.h"
#include <aio_misc.h>
int

View File

@ -1,5 +1,5 @@
/* Asynchronous read, 64bit offset version.
Copyright (C) 1997, 1999 Free Software Foundation, Inc.
Copyright (C) 1997, 1999, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@ -20,7 +20,7 @@
#include <aio.h>
#include "aio_misc.h"
#include <aio_misc.h>
int

View File

@ -1,5 +1,5 @@
/* Suspend until termination of a requests.
Copyright (C) 1997,1998,1999,2000,2002,2003 Free Software Foundation, Inc.
Copyright (C) 1997-2000,2002,2003,2005,2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@ -36,7 +36,7 @@
#include <sys/time.h>
#include <bits/libc-lock.h>
#include "aio_misc.h"
#include <aio_misc.h>
struct clparam
@ -44,7 +44,9 @@ struct clparam
const struct aiocb *const *list;
struct waitlist *waitlist;
struct requestlist **requestlist;
#ifndef DONT_NEED_AIO_MISC_COND
pthread_cond_t *cond;
#endif
int nent;
};
@ -52,6 +54,12 @@ struct clparam
static void
cleanup (void *arg)
{
#ifdef DONT_NEED_AIO_MISC_COND
/* Acquire the mutex. If pthread_cond_*wait is used this would
happen implicitly. */
pthread_mutex_lock (&__aio_requests_mutex);
#endif
const struct clparam *param = (const struct clparam *) arg;
/* Now remove the entry in the waiting list for all requests
@ -75,8 +83,10 @@ cleanup (void *arg)
*listp = (*listp)->next;
}
#ifndef DONT_NEED_AIO_MISC_COND
/* Release the conditional variable. */
(void) pthread_cond_destroy (param->cond);
#endif
/* Release the mutex. */
pthread_mutex_unlock (&__aio_requests_mutex);
@ -89,13 +99,21 @@ aio_suspend (list, nent, timeout)
int nent;
const struct timespec *timeout;
{
if (__builtin_expect (nent < 0, 0))
{
__set_errno (EINVAL);
return -1;
}
struct waitlist waitlist[nent];
struct requestlist *requestlist[nent];
#ifndef DONT_NEED_AIO_MISC_COND
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
#endif
int cnt;
bool any = false;
int result = 0;
int dummy;
int cntr = 1;
/* Request the mutex. */
pthread_mutex_lock (&__aio_requests_mutex);
@ -111,9 +129,12 @@ aio_suspend (list, nent, timeout)
if (requestlist[cnt] != NULL)
{
#ifndef DONT_NEED_AIO_MISC_COND
waitlist[cnt].cond = &cond;
#endif
waitlist[cnt].result = NULL;
waitlist[cnt].next = requestlist[cnt]->waiting;
waitlist[cnt].counterp = &dummy;
waitlist[cnt].counterp = &cntr;
waitlist[cnt].sigevp = NULL;
#ifdef BROKEN_THREAD_SIGNALS
waitlist[cnt].caller_pid = 0; /* Not needed. */
@ -139,12 +160,17 @@ aio_suspend (list, nent, timeout)
.list = list,
.waitlist = waitlist,
.requestlist = requestlist,
#ifndef DONT_NEED_AIO_MISC_COND
.cond = &cond,
#endif
.nent = nent
};
pthread_cleanup_push (cleanup, &clparam);
#ifdef DONT_NEED_AIO_MISC_COND
AIO_MISC_WAIT (result, cntr, timeout, 1);
#else
if (timeout == NULL)
result = pthread_cond_wait (&cond, &__aio_requests_mutex);
else
@ -166,6 +192,7 @@ aio_suspend (list, nent, timeout)
result = pthread_cond_timedwait (&cond, &__aio_requests_mutex,
&abstime);
}
#endif
pthread_cleanup_pop (0);
}
@ -189,19 +216,23 @@ aio_suspend (list, nent, timeout)
*listp = (*listp)->next;
}
#ifndef DONT_NEED_AIO_MISC_COND
/* Release the conditional variable. */
if (__builtin_expect (pthread_cond_destroy (&cond) != 0, 0))
/* This must never happen. */
abort ();
#endif
if (result != 0)
{
/* An error occurred. Possibly it's EINTR. We have to translate
#ifndef DONT_NEED_AIO_MISC_COND
/* An error occurred. Possibly it's ETIMEDOUT. We have to translate
the timeout error report of `pthread_cond_timedwait' to the
form expected from `aio_suspend'. */
if (result == ETIMEDOUT)
__set_errno (EAGAIN);
else
#endif
__set_errno (result);
result = -1;

View File

@ -1,5 +1,5 @@
/* Asynchronous write.
Copyright (C) 1997, 1999 Free Software Foundation, Inc.
Copyright (C) 1997, 1999, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@ -20,7 +20,7 @@
#include <aio.h>
#include "aio_misc.h"
#include <aio_misc.h>
int

View File

@ -1,5 +1,5 @@
/* Asynchronous write, 64bit offset version.
Copyright (C) 1997, 1999 Free Software Foundation, Inc.
Copyright (C) 1997, 1999, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@ -20,7 +20,7 @@
#include <aio.h>
#include "aio_misc.h"
#include <aio_misc.h>
int

View File

@ -1,3 +1,3 @@
# Local configure fragment for sysdeps/unix/sysv/linux.
# Local configure fragment for sysdeps/pthread.
DEFINES="$DEFINES -D_LIBC_REENTRANT"

View File

@ -1,5 +1,6 @@
/* Enqueue and list of read or write requests.
Copyright (C) 1997,1998,1999,2000,2001,2003 Free Software Foundation, Inc.
Copyright (C) 1997,1998,1999,2000,2001,2003,2005,2006
Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@ -25,11 +26,14 @@
#include <stdlib.h>
#include <unistd.h>
#include "aio_misc.h"
#include <aio_misc.h>
#define LIO_OPCODE_BASE 0
#endif
#include <shlib-compat.h>
/* We need this special structure to handle asynchronous I/O. */
struct async_waitlist
{
@ -39,12 +43,22 @@ struct async_waitlist
};
int
lio_listio (mode, list, nent, sig)
int mode;
struct aiocb *const list[];
int nent;
struct sigevent *sig;
/* The code in glibc 2.1 to glibc 2.4 issued only one event when all
requests submitted with lio_listio finished. The existing practice
is to issue events for the individual requests as well. This is
what the new code does. */
#if SHLIB_COMPAT (librt, GLIBC_2_1, GLIBC_2_4)
# define LIO_MODE(mode) ((mode) & 127)
# define NO_INDIVIDUAL_EVENT_P(mode) ((mode) & 128)
#else
# define LIO_MODE(mode) mode
# define NO_INDIVIDUAL_EVENT_P(mode) 0
#endif
static int
lio_listio_internal (int mode, struct aiocb *const list[], int nent,
struct sigevent *sig)
{
struct sigevent defsigev;
struct requestlist *requests[nent];
@ -52,13 +66,6 @@ lio_listio (mode, list, nent, sig)
volatile int total = 0;
int result = 0;
/* Check arguments. */
if (mode != LIO_WAIT && mode != LIO_NOWAIT)
{
__set_errno (EINVAL);
return -1;
}
if (sig == NULL)
{
defsigev.sigev_notify = SIGEV_NONE;
@ -73,7 +80,9 @@ lio_listio (mode, list, nent, sig)
for (cnt = 0; cnt < nent; ++cnt)
if (list[cnt] != NULL && list[cnt]->aio_lio_opcode != LIO_NOP)
{
list[cnt]->aio_sigevent.sigev_notify = SIGEV_NONE;
if (NO_INDIVIDUAL_EVENT_P (mode))
list[cnt]->aio_sigevent.sigev_notify = SIGEV_NONE;
requests[cnt] = __aio_enqueue_request ((aiocb_union *) list[cnt],
(list[cnt]->aio_lio_opcode
| LIO_OPCODE_BASE));
@ -99,7 +108,7 @@ lio_listio (mode, list, nent, sig)
locked forever. */
pthread_mutex_unlock (&__aio_requests_mutex);
if (mode == LIO_NOWAIT)
if (LIO_MODE (mode) == LIO_NOWAIT)
{
#ifdef BROKEN_THREAD_SIGNALS
__aio_notify_only (sig,
@ -111,11 +120,13 @@ lio_listio (mode, list, nent, sig)
return result;
}
else if (mode == LIO_WAIT)
else if (LIO_MODE (mode) == LIO_WAIT)
{
#ifndef DONT_NEED_AIO_MISC_COND
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
struct waitlist waitlist[nent];
int oldstate;
#endif
struct waitlist waitlist[nent];
total = 0;
for (cnt = 0; cnt < nent; ++cnt)
@ -124,7 +135,10 @@ lio_listio (mode, list, nent, sig)
if (requests[cnt] != NULL && list[cnt]->aio_lio_opcode != LIO_NOP)
{
#ifndef DONT_NEED_AIO_MISC_COND
waitlist[cnt].cond = &cond;
#endif
waitlist[cnt].result = &result;
waitlist[cnt].next = requests[cnt]->waiting;
waitlist[cnt].counterp = &total;
waitlist[cnt].sigevp = NULL;
@ -136,21 +150,32 @@ lio_listio (mode, list, nent, sig)
}
}
/* Since `pthread_cond_wait'/`pthread_cond_timedwait' are cancelation
#ifdef DONT_NEED_AIO_MISC_COND
AIO_MISC_WAIT (result, total, NULL, 0);
#else
/* Since `pthread_cond_wait'/`pthread_cond_timedwait' are cancellation
points we must be careful. We added entries to the waiting lists
which we must remove. So defer cancelation for now. */
which we must remove. So defer cancellation for now. */
pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &oldstate);
while (total > 0)
pthread_cond_wait (&cond, &__aio_requests_mutex);
/* Now it's time to restore the cancelation state. */
/* Now it's time to restore the cancellation state. */
pthread_setcancelstate (oldstate, NULL);
/* Release the conditional variable. */
if (pthread_cond_destroy (&cond) != 0)
/* This must never happen. */
abort ();
#endif
/* If any of the I/O requests failed, return -1 and set errno. */
if (result != 0)
{
__set_errno (result == EINTR ? EINTR : EIO);
result = -1;
}
}
else
{
@ -179,7 +204,10 @@ lio_listio (mode, list, nent, sig)
if (requests[cnt] != NULL
&& list[cnt]->aio_lio_opcode != LIO_NOP)
{
#ifndef DONT_NEED_AIO_MISC_COND
waitlist->list[cnt].cond = NULL;
#endif
waitlist->list[cnt].result = NULL;
waitlist->list[cnt].next = requests[cnt]->waiting;
waitlist->list[cnt].counterp = &waitlist->counter;
waitlist->list[cnt].sigevp = &waitlist->sigev;
@ -201,3 +229,38 @@ lio_listio (mode, list, nent, sig)
return result;
}
#if SHLIB_COMPAT (librt, GLIBC_2_1, GLIBC_2_4)
int
attribute_compat_text_section
__lio_listio_21 (int mode, struct aiocb *const list[], int nent,
struct sigevent *sig)
{
/* Check arguments. */
if (mode != LIO_WAIT && mode != LIO_NOWAIT)
{
__set_errno (EINVAL);
return -1;
}
return lio_listio_internal (mode | LIO_NO_INDIVIDUAL_EVENT, list, nent, sig);
}
compat_symbol (librt, __lio_listio_21, lio_listio, GLIBC_2_1);
#endif
int
__lio_listio_item_notify (int mode, struct aiocb *const list[], int nent,
struct sigevent *sig)
{
/* Check arguments. */
if (mode != LIO_WAIT && mode != LIO_NOWAIT)
{
__set_errno (EINVAL);
return -1;
}
return lio_listio_internal (mode, list, nent, sig);
}
versioned_symbol (librt, __lio_listio_item_notify, lio_listio, GLIBC_2_4);

View File

@ -1,5 +1,5 @@
/* Enqueue and list of read or write requests, 64bit offset version.
Copyright (C) 1997, 1998, 1999, 2003 Free Software Foundation, Inc.
Copyright (C) 1997,1998,1999,2003,2005,2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@ -24,9 +24,11 @@
#include <stdlib.h>
#include <unistd.h>
#include "aio_misc.h"
#include <aio_misc.h>
#define lio_listio lio_listio64
#define __lio_listio_21 __lio_listio64_21
#define __lio_listio_item_notify __lio_listio64_item_notify
#define aiocb aiocb64
#define LIO_OPCODE_BASE 128
#include <lio_listio.c>