diff options
author | raf <none@none> | 2006-06-20 19:21:46 -0700 |
---|---|---|
committer | raf <none@none> | 2006-06-20 19:21:46 -0700 |
commit | f841f6ad96ea6675d6c6b35c749eaac601799fdf (patch) | |
tree | 698db5d44fc99bd070613c93a497f5e93e803bc5 /usr/src/lib/libc/inc/asyncio.h | |
parent | 545e5dad7996785cfebf226c5ef410c1b154740f (diff) | |
download | illumos-joyent-f841f6ad96ea6675d6c6b35c749eaac601799fdf.tar.gz |
6416832 libaio and librt can and should be folded into libc
--HG--
rename : usr/src/cmd/perl/5.8.4/distrib/ext/Time/HiRes/hints/solaris.pl => deleted_files/usr/src/cmd/perl/5.8.4/distrib/ext/Time/HiRes/hints/solaris.pl
rename : usr/src/lib/libaio/common/Makefile => deleted_files/usr/src/lib/libaio/common/Makefile
rename : usr/src/lib/libaio/common/scalls.c => deleted_files/usr/src/lib/libaio/common/scalls.c
rename : usr/src/lib/libaio/common/sig.c => deleted_files/usr/src/lib/libaio/common/sig.c
rename : usr/src/lib/libaio/common/subr.c => deleted_files/usr/src/lib/libaio/common/subr.c
rename : usr/src/lib/libaio/spec/Makefile => deleted_files/usr/src/lib/libaio/spec/Makefile
rename : usr/src/lib/libaio/spec/Makefile.targ => deleted_files/usr/src/lib/libaio/spec/Makefile.targ
rename : usr/src/lib/libaio/spec/amd64/Makefile => deleted_files/usr/src/lib/libaio/spec/amd64/Makefile
rename : usr/src/lib/libaio/spec/i386/Makefile => deleted_files/usr/src/lib/libaio/spec/i386/Makefile
rename : usr/src/lib/libaio/spec/sparc/Makefile => deleted_files/usr/src/lib/libaio/spec/sparc/Makefile
rename : usr/src/lib/libaio/spec/sparcv9/Makefile => deleted_files/usr/src/lib/libaio/spec/sparcv9/Makefile
rename : usr/src/lib/libaio/spec/versions => deleted_files/usr/src/lib/libaio/spec/versions
rename : usr/src/lib/librt/common/Makefile => deleted_files/usr/src/lib/librt/common/Makefile
rename : usr/src/lib/librt/common/aio.c => deleted_files/usr/src/lib/librt/common/aio.c
rename : usr/src/lib/librt/common/fdatasync.c => deleted_files/usr/src/lib/librt/common/fdatasync.c
rename : usr/src/lib/librt/common/mqlib.h => deleted_files/usr/src/lib/librt/common/mqlib.h
rename : usr/src/lib/librt/common/pos4.c => deleted_files/usr/src/lib/librt/common/pos4.c
rename : usr/src/lib/librt/common/pos4.h => deleted_files/usr/src/lib/librt/common/pos4.h
rename : usr/src/lib/librt/common/sigrt.c => deleted_files/usr/src/lib/librt/common/sigrt.c
rename : usr/src/lib/librt/req.flg => deleted_files/usr/src/lib/librt/req.flg
rename : usr/src/lib/librt/spec/Makefile => deleted_files/usr/src/lib/librt/spec/Makefile
rename : usr/src/lib/librt/spec/Makefile.targ => deleted_files/usr/src/lib/librt/spec/Makefile.targ
rename : usr/src/lib/librt/spec/amd64/Makefile => deleted_files/usr/src/lib/librt/spec/amd64/Makefile
rename : usr/src/lib/librt/spec/i386/Makefile => deleted_files/usr/src/lib/librt/spec/i386/Makefile
rename : usr/src/lib/librt/spec/sparc/Makefile => deleted_files/usr/src/lib/librt/spec/sparc/Makefile
rename : usr/src/lib/librt/spec/sparcv9/Makefile => deleted_files/usr/src/lib/librt/spec/sparcv9/Makefile
rename : usr/src/lib/librt/spec/versions => deleted_files/usr/src/lib/librt/spec/versions
rename : usr/src/lib/libaio/common/libaio.h => usr/src/lib/libc/inc/asyncio.h
rename : usr/src/lib/librt/common/thread_pool.h => usr/src/lib/libc/inc/thread_pool.h
rename : usr/src/lib/libaio/common/aio.c => usr/src/lib/libc/port/aio/aio.c
rename : usr/src/lib/libaio/common/ma.c => usr/src/lib/libc/port/aio/aio_alloc.c
rename : usr/src/lib/libaio/common/posix_aio.c => usr/src/lib/libc/port/aio/posix_aio.c
rename : usr/src/lib/librt/common/clock_timer.c => usr/src/lib/libc/port/rt/clock_timer.c
rename : usr/src/lib/librt/common/fallocate.c => usr/src/lib/libc/port/rt/fallocate.c
rename : usr/src/lib/librt/common/mqueue.c => usr/src/lib/libc/port/rt/mqueue.c
rename : usr/src/lib/librt/common/pos4obj.c => usr/src/lib/libc/port/rt/pos4obj.c
rename : usr/src/lib/librt/common/pos4obj.h => usr/src/lib/libc/port/rt/pos4obj.h
rename : usr/src/lib/librt/common/sched.c => usr/src/lib/libc/port/rt/sched.c
rename : usr/src/lib/librt/common/sem.c => usr/src/lib/libc/port/rt/sem.c
rename : usr/src/lib/librt/common/shm.c => usr/src/lib/libc/port/rt/shm.c
rename : usr/src/lib/librt/common/sigev_thread.c => usr/src/lib/libc/port/rt/sigev_thread.c
rename : usr/src/lib/librt/common/sigev_thread.h => usr/src/lib/libc/port/rt/sigev_thread.h
rename : usr/src/lib/librt/common/thread_pool.c => usr/src/lib/libc/port/tpool/thread_pool.c
rename : usr/src/lib/librt/common/thread_pool_impl.h => usr/src/lib/libc/port/tpool/thread_pool_impl.h
rename : usr/src/lib/libaio/spec/aio.spec => usr/src/lib/libc/spec/aio.spec
rename : usr/src/lib/librt/spec/rt.spec => usr/src/lib/libc/spec/rt.spec
rename : usr/src/lib/libaio/asynch.h => usr/src/uts/common/sys/asynch.h
Diffstat (limited to 'usr/src/lib/libc/inc/asyncio.h')
-rw-r--r-- | usr/src/lib/libc/inc/asyncio.h | 346 |
1 files changed, 346 insertions, 0 deletions
diff --git a/usr/src/lib/libc/inc/asyncio.h b/usr/src/lib/libc/inc/asyncio.h new file mode 100644 index 0000000000..02d33cd700 --- /dev/null +++ b/usr/src/lib/libc/inc/asyncio.h @@ -0,0 +1,346 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _ASYNCIO_H +#define _ASYNCIO_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <thread.h> +#include <pthread.h> +#include <setjmp.h> +#include <signal.h> +#include <siginfo.h> +#include <aio.h> +#include <limits.h> +#include <ucontext.h> +#include <sys/asynch.h> +#include <sys/mman.h> + +#if !defined(_LP64) +#define AIOSTKSIZE (64 * 1024) +#else +#define AIOSTKSIZE (128 * 1024) +#endif + +#define SIGAIOCANCEL SIGLWP /* special aio cancelation signal */ + +#define AIO_WAITN_MAXIOCBS 32768 /* max. iocbs per system call */ + +/* + * Declare structure types. The structures themselves are defined below. + */ +typedef struct aio_args aio_args_t; +typedef struct aio_lio aio_lio_t; +typedef struct notif_param notif_param_t; +typedef struct aio_req aio_req_t; +typedef struct aio_worker aio_worker_t; +typedef struct aio_hash aio_hash_t; + +struct aio_args { + int fd; + caddr_t buf; + size_t bufsz; + offset_t offset; +}; + +/* + * list head for UFS list I/O + */ +struct aio_lio { + mutex_t lio_mutex; /* list mutex */ + cond_t lio_cond_cv; /* list notification for I/O done */ + aio_lio_t *lio_next; /* pointer to next on freelist */ + char lio_mode; /* LIO_WAIT/LIO_NOWAIT */ + char lio_canned; /* lio was canceled */ + char lio_largefile; /* largefile operation */ + char lio_waiting; /* waiting in __lio_listio() */ + int lio_nent; /* Number of list I/O's */ + int lio_refcnt; /* outstanding I/O's */ + int lio_event; /* Event number for notification */ + int lio_port; /* Port number for notification */ + int lio_signo; /* Signal number for notification */ + union sigval lio_sigval; /* Signal parameter */ + uintptr_t lio_object; /* for SIGEV_THREAD or SIGEV_PORT */ + struct sigevent *lio_sigevent; /* Notification function and attr. */ +}; + +/* + * Notification parameters + */ +struct notif_param { + int np_signo; /* SIGEV_SIGNAL */ + int np_port; /* SIGEV_THREAD or SIGEV_PORT */ + void *np_user; + int np_event; + uintptr_t np_object; + int np_lio_signo; /* listio: SIGEV_SIGNAL */ + int np_lio_port; /* listio: SIGEV_THREAD or SIGEV_PORT */ + void *np_lio_user; + int np_lio_event; + uintptr_t np_lio_object; +}; + +struct aio_req { + /* + * fields protected by _aio_mutex lock. + */ + aio_req_t *req_link; /* hash/freelist chain link */ + /* + * when req is on the doneq, then req_next is protected by + * the _aio_mutex lock. when the req is on a work q, then + * req_next is protected by a worker's work_qlock1 lock. + */ + aio_req_t *req_next; /* request/done queue link */ + aio_req_t *req_prev; /* double linked list */ + /* + * fields protected by a worker's work_qlock1 lock. + */ + char req_state; /* AIO_REQ_QUEUED, ... */ + /* + * fields require no locking. + */ + char req_type; /* AIO_POSIX_REQ or not */ + char req_largefile; /* largefile operation */ + char req_op; /* AIOREAD, etc. */ + aio_worker_t *req_worker; /* associate request with worker */ + aio_result_t *req_resultp; /* address of result buffer */ + aio_args_t req_args; /* arglist */ + aio_lio_t *req_head; /* list head for LIO */ + struct sigevent req_sigevent; + void *req_aiocbp; /* ptr to aiocb or aiocb64 */ + notif_param_t req_notify; /* notification parameters */ +}; + +/* special lio type that destroys itself when lio refcnt becomes zero */ +#define LIO_FSYNC LIO_WAIT+1 +#define LIO_DESTROY LIO_FSYNC+1 + +/* lio flags */ +#define LIO_FSYNC_CANCELED 0x1 + +/* values for aio_state */ + +#define AIO_REQ_QUEUED 1 +#define AIO_REQ_INPROGRESS 2 +#define AIO_REQ_CANCELED 3 +#define AIO_REQ_DONE 4 +#define AIO_REQ_FREE 5 +#define AIO_REQ_DONEQ 6 + +/* use KAIO in _aio_rw() */ +#define AIO_NO_KAIO 0x0 +#define AIO_KAIO 0x1 +#define AIO_NO_DUPS 0x2 + +#define AIO_POSIX_REQ 0x1 + +#define CHECK 1 +#define NOCHECK 2 +#define CHECKED 3 +#define USERAIO 4 +#define USERAIO_DONE 5 + +/* values for _aio_flags */ + +/* if set, _aiodone() notifies aio_waitn about done requests */ +#define AIO_WAIT_INPROGRESS 0x1 +/* if set, _aiodone() wakes up functions waiting for completed I/Os */ +#define AIO_IO_WAITING 0x2 +#define AIO_LIB_WAITN 0x4 /* aio_waitn in progress */ +#define AIO_LIB_WAITN_PENDING 0x8 /* aio_waitn requests pending */ + +/* + * Before a kaio() system call, the fd will be checked + * to ensure that kernel async. I/O is supported for this file. + * The only way to find out is if a kaio() call returns ENOTSUP, + * so the default will always be to try the kaio() call. Only in + * the specific instance of a kaio() call returning ENOTSUP + * will we stop submitting kaio() calls for that fd. + * If the fd is outside the array bounds, we will allow the kaio() + * call. + * + * The only way that an fd entry can go from ENOTSUP to supported + * is if that fd is freed up by a close(), and close will clear + * the entry for that fd. + * + * Each fd gets a bit in the array _kaio_supported[]. + * + * uint32_t _kaio_supported[MAX_KAIO_FDARRAY_SIZE]; + * + * Array is MAX_KAIO_ARRAY_SIZE of 32-bit elements, for 8kb. + * If more than (MAX_KAIO_FDARRAY_SIZE * KAIO_FDARRAY_ELEM_SIZE) + * files are open, this can be expanded. + */ + +#define MAX_KAIO_FDARRAY_SIZE 2048 +#define KAIO_FDARRAY_ELEM_SIZE WORD_BIT /* uint32_t */ + +#define MAX_KAIO_FDS (MAX_KAIO_FDARRAY_SIZE * KAIO_FDARRAY_ELEM_SIZE) + +#define VALID_FD(fdes) ((fdes) >= 0 && (fdes) < MAX_KAIO_FDS) + +#define KAIO_SUPPORTED(fdes) \ + (!VALID_FD(fdes) || \ + ((_kaio_supported[(fdes) / KAIO_FDARRAY_ELEM_SIZE] & \ + (uint32_t)(1 << ((fdes) % KAIO_FDARRAY_ELEM_SIZE))) == 0)) + +#define SET_KAIO_NOT_SUPPORTED(fdes) \ + if (VALID_FD(fdes)) \ + _kaio_supported[(fdes) / KAIO_FDARRAY_ELEM_SIZE] |= \ + (uint32_t)(1 << ((fdes) % KAIO_FDARRAY_ELEM_SIZE)) + +#define CLEAR_KAIO_SUPPORTED(fdes) \ + if (VALID_FD(fdes)) \ + _kaio_supported[(fdes) / KAIO_FDARRAY_ELEM_SIZE] &= \ + ~(uint32_t)(1 << ((fdes) % KAIO_FDARRAY_ELEM_SIZE)) + +struct aio_worker { + aio_worker_t *work_forw; /* forward link in list of workers */ + aio_worker_t *work_backw; /* backwards link in list of workers */ + mutex_t work_qlock1; /* lock for work queue 1 */ + cond_t work_idle_cv; /* place to sleep when idle */ + aio_req_t *work_head1; /* head of work request queue 1 */ + aio_req_t *work_tail1; /* tail of work request queue 1 */ + aio_req_t *work_next1; /* work queue one's next pointer */ + aio_req_t *work_prev1; /* last request done from queue 1 */ + aio_req_t *work_req; /* active work request */ + thread_t work_tid; /* worker's thread-id */ + int work_count1; /* length of work queue one */ + int work_done1; /* number of requests done */ + int work_minload1; /* min length of queue */ + int work_idleflg; /* when set, worker is idle */ + sigjmp_buf work_jmp_buf; /* cancellation point */ +}; + +struct aio_hash { /* resultp hash table */ + mutex_t hash_lock; + aio_req_t *hash_ptr; +#if !defined(_LP64) + void *hash_pad; /* ensure sizeof (aio_hash_t) == 32 */ +#endif +}; + +extern aio_hash_t *_aio_hash; + +#define HASHSZ 2048 /* power of 2 */ +#define AIOHASH(resultp) ((((uintptr_t)(resultp) >> 17) ^ \ + ((uintptr_t)(resultp) >> 2)) & (HASHSZ - 1)) +#define POSIX_AIO(x) ((x)->req_type == AIO_POSIX_REQ) + +extern int __uaio_init(void); +extern void _kaio_init(void); +extern intptr_t _kaio(int, ...); +extern int _aiorw(int, caddr_t, int, offset_t, int, aio_result_t *, int); +extern int _aio_rw(aiocb_t *, aio_lio_t *, aio_worker_t **, int, int); +#if !defined(_LP64) +extern int _aio_rw64(aiocb64_t *, aio_lio_t *, aio_worker_t **, int, int); +#endif +extern int _aio_create_worker(aio_req_t *, int); +extern int _aio_cancel_req(aio_worker_t *, aio_req_t *, int *, int *); +extern int aiocancel_all(int); +extern void aio_panic(const char *); +extern aio_req_t *_aio_hash_find(aio_result_t *); +extern aio_req_t *_aio_hash_del(aio_result_t *); +extern void _aio_req_mark_done(aio_req_t *); +extern void _aio_waitn_wakeup(void); +extern aio_worker_t *_aio_worker_alloc(void); +extern void _aio_worker_free(void *); +extern aio_req_t *_aio_req_alloc(void); +extern void _aio_req_free(aio_req_t *); +extern aio_lio_t *_aio_lio_alloc(void); +extern void _aio_lio_free(aio_lio_t *); +extern int _aio_idle(aio_worker_t *); +extern void *_aio_do_request(void *); +extern void *_aio_do_notify(void *); +extern void _lio_remove(aio_req_t *); +extern aio_req_t *_aio_req_remove(aio_req_t *); +extern int _aio_get_timedelta(timespec_t *, timespec_t *); +extern aio_result_t *_aio_req_done(void); +extern void _aio_set_result(aio_req_t *, ssize_t, int); +extern int _aio_sigev_thread_init(struct sigevent *); +extern int _aio_sigev_thread(aiocb_t *); +#if !defined(_LP64) +extern int _aio_sigev_thread64(aiocb64_t *); +#endif + +extern aio_worker_t *_kaiowp; /* points to kaio cleanup thread */ +extern aio_worker_t *__workers_rw; /* list of all rw workers */ +extern aio_worker_t *__nextworker_rw; /* worker chosen for next rw request */ +extern int __rw_workerscnt; /* number of rw workers */ +extern aio_worker_t *__workers_no; /* list of all notification workers */ +extern aio_worker_t *__nextworker_no; /* worker chosen, next notification */ +extern int __no_workerscnt; /* number of notification workers */ +extern mutex_t __aio_initlock; /* makes aio initialization atomic */ +extern cond_t __aio_initcv; +extern int __aio_initbusy; +extern mutex_t __aio_mutex; /* global aio lock */ +extern cond_t _aio_iowait_cv; /* wait for userland I/Os */ +extern cond_t _aio_waitn_cv; /* wait for end of aio_waitn */ +extern int _max_workers; /* max number of workers permitted */ +extern int _min_workers; /* min number of workers */ +extern sigset_t _worker_set; /* worker's signal mask */ +extern int _aio_worker_cnt; /* number of AIO workers */ +extern int _sigio_enabled; /* when set, send SIGIO signal */ +extern pid_t __pid; /* process's PID */ +extern int __uaio_ok; /* indicates if aio is initialized */ +extern int _kaio_ok; /* indicates if kaio is initialized */ +extern pthread_key_t _aio_key; /* for thread-specific data */ +extern aio_req_t *_aio_done_tail; /* list of done requests */ +extern aio_req_t *_aio_done_head; +extern aio_req_t *_aio_doneq; +extern int _aio_freelist_cnt; +extern int _aio_allocated_cnt; +extern int _aio_donecnt; +extern int _aio_doneq_cnt; +extern int _aio_waitncnt; /* # of requests for aio_waitn */ +extern int _aio_outstand_cnt; /* # of outstanding requests */ +extern int _kaio_outstand_cnt; /* # of outstanding kaio requests */ +extern int _aio_req_done_cnt; /* req. done but not in "done queue" */ +extern int _aio_kernel_suspend; /* active kernel kaio calls */ +extern int _aio_suscv_cnt; /* aio_suspend calls waiting on cv's */ +extern int _aiowait_flag; /* when set, aiowait() is inprogress */ +extern int _aio_flags; /* see defines, above */ +extern uint32_t *_kaio_supported; + +extern const sigset_t maskset; /* all maskable signals */ + +#ifdef __cplusplus +} +#endif + +#endif /* _ASYNCIO_H */ |