xref: /illumos-gate/usr/src/lib/libc/inc/asyncio.h (revision 1da57d55)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
534709573Sraf  * Common Development and Distribution License (the "License").
634709573Sraf  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
2134709573Sraf 
227c478bd9Sstevel@tonic-gate /*
2334709573Sraf  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
27*f841f6adSraf #ifndef	_ASYNCIO_H
28*f841f6adSraf #define	_ASYNCIO_H
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
317c478bd9Sstevel@tonic-gate extern "C" {
327c478bd9Sstevel@tonic-gate #endif
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate #include <stdio.h>
357c478bd9Sstevel@tonic-gate #include <stdlib.h>
367c478bd9Sstevel@tonic-gate #include <unistd.h>
377c478bd9Sstevel@tonic-gate #include <string.h>
387c478bd9Sstevel@tonic-gate #include <errno.h>
397c478bd9Sstevel@tonic-gate #include <sys/types.h>
407c478bd9Sstevel@tonic-gate #include <sys/stat.h>
417c478bd9Sstevel@tonic-gate #include <thread.h>
4234709573Sraf #include <pthread.h>
437c478bd9Sstevel@tonic-gate #include <setjmp.h>
447c478bd9Sstevel@tonic-gate #include <signal.h>
457c478bd9Sstevel@tonic-gate #include <siginfo.h>
467c478bd9Sstevel@tonic-gate #include <aio.h>
477c478bd9Sstevel@tonic-gate #include <limits.h>
487c478bd9Sstevel@tonic-gate #include <ucontext.h>
49*f841f6adSraf #include <sys/asynch.h>
5034709573Sraf #include <sys/mman.h>
517c478bd9Sstevel@tonic-gate 
5234709573Sraf #if !defined(_LP64)
5334709573Sraf #define	AIOSTKSIZE	(64 * 1024)
5434709573Sraf #else
5534709573Sraf #define	AIOSTKSIZE	(128 * 1024)
5634709573Sraf #endif
5734709573Sraf 
5834709573Sraf #define	SIGAIOCANCEL		SIGLWP	/* special aio cancelation signal */
5934709573Sraf 
607c478bd9Sstevel@tonic-gate #define	AIO_WAITN_MAXIOCBS	32768	/* max. iocbs per system call */
617c478bd9Sstevel@tonic-gate 
6234709573Sraf /*
6334709573Sraf  * Declare structure types.  The structures themselves are defined below.
6434709573Sraf  */
6534709573Sraf typedef struct aio_args		aio_args_t;
6634709573Sraf typedef struct aio_lio		aio_lio_t;
6734709573Sraf typedef struct notif_param	notif_param_t;
6834709573Sraf typedef struct aio_req		aio_req_t;
6934709573Sraf typedef struct aio_worker	aio_worker_t;
7034709573Sraf typedef struct aio_hash		aio_hash_t;
7134709573Sraf 
7234709573Sraf struct aio_args {
737c478bd9Sstevel@tonic-gate 	int 		fd;
747c478bd9Sstevel@tonic-gate 	caddr_t		buf;
757c478bd9Sstevel@tonic-gate 	size_t		bufsz;
767c478bd9Sstevel@tonic-gate 	offset_t	offset;
7734709573Sraf };
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate /*
807c478bd9Sstevel@tonic-gate  * list head for UFS list I/O
817c478bd9Sstevel@tonic-gate  */
8234709573Sraf struct aio_lio {
8334709573Sraf 	mutex_t		lio_mutex;	/* list mutex */
847c478bd9Sstevel@tonic-gate 	cond_t		lio_cond_cv;	/* list notification for I/O done */
8534709573Sraf 	aio_lio_t	*lio_next;	/* pointer to next on freelist */
8634709573Sraf 	char		lio_mode;	/* LIO_WAIT/LIO_NOWAIT */
877c478bd9Sstevel@tonic-gate 	char		lio_canned;	/* lio was canceled */
8834709573Sraf 	char		lio_largefile;	/* largefile operation */
8934709573Sraf 	char		lio_waiting;	/* waiting in __lio_listio() */
9034709573Sraf 	int		lio_nent;	/* Number of list I/O's */
9134709573Sraf 	int		lio_refcnt;	/* outstanding I/O's */
9234709573Sraf 	int		lio_event;	/* Event number for notification */
9334709573Sraf 	int		lio_port;	/* Port number for notification */
9434709573Sraf 	int		lio_signo;	/* Signal number for notification */
9534709573Sraf 	union sigval	lio_sigval;	/* Signal parameter */
9634709573Sraf 	uintptr_t	lio_object;	/* for SIGEV_THREAD or SIGEV_PORT */
9734709573Sraf 	struct sigevent	*lio_sigevent;	/* Notification function and attr. */
9834709573Sraf };
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate /*
10134709573Sraf  * Notification parameters
1027c478bd9Sstevel@tonic-gate  */
10334709573Sraf struct notif_param {
10434709573Sraf 	int		np_signo;	/* SIGEV_SIGNAL */
10534709573Sraf 	int		np_port;	/* SIGEV_THREAD or SIGEV_PORT */
10634709573Sraf 	void		*np_user;
10734709573Sraf 	int		np_event;
10834709573Sraf 	uintptr_t	np_object;
10934709573Sraf 	int		np_lio_signo;	/* listio: SIGEV_SIGNAL */
11034709573Sraf 	int		np_lio_port;	/* listio: SIGEV_THREAD or SIGEV_PORT */
11134709573Sraf 	void		*np_lio_user;
11234709573Sraf 	int		np_lio_event;
11334709573Sraf 	uintptr_t	np_lio_object;
11434709573Sraf };
11534709573Sraf 
11634709573Sraf struct aio_req {
1177c478bd9Sstevel@tonic-gate 	/*
1187c478bd9Sstevel@tonic-gate 	 * fields protected by _aio_mutex lock.
1197c478bd9Sstevel@tonic-gate 	 */
12034709573Sraf 	aio_req_t *req_link;		/* hash/freelist chain link */
1217c478bd9Sstevel@tonic-gate 	/*
1227c478bd9Sstevel@tonic-gate 	 * when req is on the doneq, then req_next is protected by
1237c478bd9Sstevel@tonic-gate 	 * the _aio_mutex lock. when the req is on a work q, then
1247c478bd9Sstevel@tonic-gate 	 * req_next is protected by a worker's work_qlock1 lock.
1257c478bd9Sstevel@tonic-gate 	 */
12634709573Sraf 	aio_req_t *req_next;		/* request/done queue link */
12734709573Sraf 	aio_req_t *req_prev;		/* double linked list */
1287c478bd9Sstevel@tonic-gate 	/*
1297c478bd9Sstevel@tonic-gate 	 * fields protected by a worker's work_qlock1 lock.
1307c478bd9Sstevel@tonic-gate 	 */
13134709573Sraf 	char		req_state;	/* AIO_REQ_QUEUED, ... */
1327c478bd9Sstevel@tonic-gate 	/*
1337c478bd9Sstevel@tonic-gate 	 * fields require no locking.
1347c478bd9Sstevel@tonic-gate 	 */
13534709573Sraf 	char		req_type;	/* AIO_POSIX_REQ or not */
13634709573Sraf 	char		req_largefile;	/* largefile operation */
13734709573Sraf 	char		req_op;		/* AIOREAD, etc. */
13834709573Sraf 	aio_worker_t	*req_worker;	/* associate request with worker */
1397c478bd9Sstevel@tonic-gate 	aio_result_t	*req_resultp;	/* address of result buffer */
1407c478bd9Sstevel@tonic-gate 	aio_args_t	req_args;	/* arglist */
14134709573Sraf 	aio_lio_t	*req_head;	/* list head for LIO */
14234709573Sraf 	struct sigevent	req_sigevent;
14334709573Sraf 	void		*req_aiocbp;	/* ptr to aiocb or aiocb64 */
14434709573Sraf 	notif_param_t	req_notify;	/* notification parameters */
14534709573Sraf };
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate /* special lio type that destroys itself when lio refcnt becomes zero */
1487c478bd9Sstevel@tonic-gate #define	LIO_FSYNC	LIO_WAIT+1
1497c478bd9Sstevel@tonic-gate #define	LIO_DESTROY	LIO_FSYNC+1
1507c478bd9Sstevel@tonic-gate 
1517c478bd9Sstevel@tonic-gate /* lio flags */
1527c478bd9Sstevel@tonic-gate #define	LIO_FSYNC_CANCELED	0x1
1537c478bd9Sstevel@tonic-gate 
15434709573Sraf /* values for aio_state */
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate #define	AIO_REQ_QUEUED		1
1577c478bd9Sstevel@tonic-gate #define	AIO_REQ_INPROGRESS	2
1587c478bd9Sstevel@tonic-gate #define	AIO_REQ_CANCELED	3
1597c478bd9Sstevel@tonic-gate #define	AIO_REQ_DONE 		4
1607c478bd9Sstevel@tonic-gate #define	AIO_REQ_FREE		5
16134709573Sraf #define	AIO_REQ_DONEQ 		6
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate /* use KAIO in _aio_rw() */
1647c478bd9Sstevel@tonic-gate #define	AIO_NO_KAIO		0x0
1657c478bd9Sstevel@tonic-gate #define	AIO_KAIO		0x1
1667c478bd9Sstevel@tonic-gate #define	AIO_NO_DUPS		0x2
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate #define	AIO_POSIX_REQ		0x1
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate #define	CHECK			1
1717c478bd9Sstevel@tonic-gate #define	NOCHECK			2
1727c478bd9Sstevel@tonic-gate #define	CHECKED			3
1737c478bd9Sstevel@tonic-gate #define	USERAIO			4
1747c478bd9Sstevel@tonic-gate #define	USERAIO_DONE		5
1757c478bd9Sstevel@tonic-gate 
1767c478bd9Sstevel@tonic-gate /* values for _aio_flags */
1777c478bd9Sstevel@tonic-gate 
178*f841f6adSraf /* if set, _aiodone() notifies aio_waitn about done requests */
1797c478bd9Sstevel@tonic-gate #define	AIO_WAIT_INPROGRESS	0x1
180*f841f6adSraf /* if set, _aiodone() wakes up functions waiting for completed I/Os */
1817c478bd9Sstevel@tonic-gate #define	AIO_IO_WAITING		0x2
182*f841f6adSraf #define	AIO_LIB_WAITN		0x4	/* aio_waitn in progress */
183*f841f6adSraf #define	AIO_LIB_WAITN_PENDING	0x8	/* aio_waitn requests pending */
1847c478bd9Sstevel@tonic-gate 
1857c478bd9Sstevel@tonic-gate /*
1867c478bd9Sstevel@tonic-gate  * Before a kaio() system call, the fd will be checked
1877c478bd9Sstevel@tonic-gate  * to ensure that kernel async. I/O is supported for this file.
1887c478bd9Sstevel@tonic-gate  * The only way to find out is if a kaio() call returns ENOTSUP,
1897c478bd9Sstevel@tonic-gate  * so the default will always be to try the kaio() call. Only in
1907c478bd9Sstevel@tonic-gate  * the specific instance of a kaio() call returning ENOTSUP
1917c478bd9Sstevel@tonic-gate  * will we stop submitting kaio() calls for that fd.
1927c478bd9Sstevel@tonic-gate  * If the fd is outside the array bounds, we will allow the kaio()
1937c478bd9Sstevel@tonic-gate  * call.
1947c478bd9Sstevel@tonic-gate  *
1957c478bd9Sstevel@tonic-gate  * The only way that an fd entry can go from ENOTSUP to supported
1967c478bd9Sstevel@tonic-gate  * is if that fd is freed up by a close(), and close will clear
1977c478bd9Sstevel@tonic-gate  * the entry for that fd.
1987c478bd9Sstevel@tonic-gate  *
1997c478bd9Sstevel@tonic-gate  * Each fd gets a bit in the array _kaio_supported[].
2007c478bd9Sstevel@tonic-gate  *
2017c478bd9Sstevel@tonic-gate  * uint32_t	_kaio_supported[MAX_KAIO_FDARRAY_SIZE];
2027c478bd9Sstevel@tonic-gate  *
20334709573Sraf  * Array is MAX_KAIO_ARRAY_SIZE of 32-bit elements, for 8kb.
20434709573Sraf  * If more than (MAX_KAIO_FDARRAY_SIZE * KAIO_FDARRAY_ELEM_SIZE)
2057c478bd9Sstevel@tonic-gate  * files are open, this can be expanded.
2067c478bd9Sstevel@tonic-gate  */
2077c478bd9Sstevel@tonic-gate 
20834709573Sraf #define	MAX_KAIO_FDARRAY_SIZE		2048
2097c478bd9Sstevel@tonic-gate #define	KAIO_FDARRAY_ELEM_SIZE		WORD_BIT	/* uint32_t */
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate #define	MAX_KAIO_FDS	(MAX_KAIO_FDARRAY_SIZE * KAIO_FDARRAY_ELEM_SIZE)
2127c478bd9Sstevel@tonic-gate 
21334709573Sraf #define	VALID_FD(fdes)		((fdes) >= 0 && (fdes) < MAX_KAIO_FDS)
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate #define	KAIO_SUPPORTED(fdes)						\
21634709573Sraf 	(!VALID_FD(fdes) || 						\
2177c478bd9Sstevel@tonic-gate 		((_kaio_supported[(fdes) / KAIO_FDARRAY_ELEM_SIZE] &	\
2187c478bd9Sstevel@tonic-gate 		(uint32_t)(1 << ((fdes) % KAIO_FDARRAY_ELEM_SIZE))) == 0))
2197c478bd9Sstevel@tonic-gate 
2207c478bd9Sstevel@tonic-gate #define	SET_KAIO_NOT_SUPPORTED(fdes)					\
22134709573Sraf 	if (VALID_FD(fdes))						\
2227c478bd9Sstevel@tonic-gate 		_kaio_supported[(fdes) / KAIO_FDARRAY_ELEM_SIZE] |=	\
2237c478bd9Sstevel@tonic-gate 		(uint32_t)(1 << ((fdes) % KAIO_FDARRAY_ELEM_SIZE))
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate #define	CLEAR_KAIO_SUPPORTED(fdes)					\
22634709573Sraf 	if (VALID_FD(fdes))						\
2277c478bd9Sstevel@tonic-gate 		_kaio_supported[(fdes) / KAIO_FDARRAY_ELEM_SIZE] &=	\
2287c478bd9Sstevel@tonic-gate 		~(uint32_t)(1 << ((fdes) % KAIO_FDARRAY_ELEM_SIZE))
2297c478bd9Sstevel@tonic-gate 
23034709573Sraf struct aio_worker {
23134709573Sraf 	aio_worker_t *work_forw;	/* forward link in list of workers */
23234709573Sraf 	aio_worker_t *work_backw;	/* backwards link in list of workers */
2337c478bd9Sstevel@tonic-gate 	mutex_t work_qlock1;		/* lock for work queue 1 */
23434709573Sraf 	cond_t work_idle_cv;		/* place to sleep when idle */
23534709573Sraf 	aio_req_t *work_head1;		/* head of work request queue 1 */
23634709573Sraf 	aio_req_t *work_tail1;		/* tail of work request queue 1 */
23734709573Sraf 	aio_req_t *work_next1;		/* work queue one's next pointer */
23834709573Sraf 	aio_req_t *work_prev1;		/* last request done from queue 1 */
23934709573Sraf 	aio_req_t *work_req;		/* active work request */
24034709573Sraf 	thread_t work_tid;		/* worker's thread-id */
24134709573Sraf 	int work_count1;		/* length of work queue one */
2427c478bd9Sstevel@tonic-gate 	int work_done1;			/* number of requests done */
2437c478bd9Sstevel@tonic-gate 	int work_minload1;		/* min length of queue */
2447c478bd9Sstevel@tonic-gate 	int work_idleflg;		/* when set, worker is idle */
2457c478bd9Sstevel@tonic-gate 	sigjmp_buf work_jmp_buf;	/* cancellation point */
24634709573Sraf };
24734709573Sraf 
24834709573Sraf struct aio_hash {			/* resultp hash table */
24934709573Sraf 	mutex_t		hash_lock;
25034709573Sraf 	aio_req_t	*hash_ptr;
25134709573Sraf #if !defined(_LP64)
25234709573Sraf 	void		*hash_pad;	/* ensure sizeof (aio_hash_t) == 32 */
25334709573Sraf #endif
25434709573Sraf };
25534709573Sraf 
25634709573Sraf extern aio_hash_t *_aio_hash;
25734709573Sraf 
25834709573Sraf #define	HASHSZ			2048	/* power of 2 */
25934709573Sraf #define	AIOHASH(resultp)	((((uintptr_t)(resultp) >> 17) ^ \
26034709573Sraf 				((uintptr_t)(resultp) >> 2)) & (HASHSZ - 1))
26134709573Sraf #define	POSIX_AIO(x)		((x)->req_type == AIO_POSIX_REQ)
2627c478bd9Sstevel@tonic-gate 
26334709573Sraf extern int __uaio_init(void);
2647c478bd9Sstevel@tonic-gate extern void _kaio_init(void);
2657c478bd9Sstevel@tonic-gate extern intptr_t _kaio(int, ...);
2667c478bd9Sstevel@tonic-gate extern int _aiorw(int, caddr_t, int, offset_t, int, aio_result_t *, int);
26734709573Sraf extern int _aio_rw(aiocb_t *, aio_lio_t *, aio_worker_t **, int, int);
26834709573Sraf #if !defined(_LP64)
26934709573Sraf extern int _aio_rw64(aiocb64_t *, aio_lio_t *, aio_worker_t **, int, int);
2707c478bd9Sstevel@tonic-gate #endif
2717c478bd9Sstevel@tonic-gate extern int _aio_create_worker(aio_req_t *, int);
2727c478bd9Sstevel@tonic-gate extern int _aio_cancel_req(aio_worker_t *, aio_req_t *, int *, int *);
27334709573Sraf extern int aiocancel_all(int);
274*f841f6adSraf extern void aio_panic(const char *);
27534709573Sraf extern aio_req_t *_aio_hash_find(aio_result_t *);
2767c478bd9Sstevel@tonic-gate extern aio_req_t *_aio_hash_del(aio_result_t *);
27734709573Sraf extern void _aio_req_mark_done(aio_req_t *);
27834709573Sraf extern void _aio_waitn_wakeup(void);
27934709573Sraf extern aio_worker_t *_aio_worker_alloc(void);
28034709573Sraf extern void _aio_worker_free(void *);
28134709573Sraf extern aio_req_t *_aio_req_alloc(void);
28234709573Sraf extern void _aio_req_free(aio_req_t *);
28334709573Sraf extern aio_lio_t *_aio_lio_alloc(void);
28434709573Sraf extern void _aio_lio_free(aio_lio_t *);
285*f841f6adSraf extern int _aio_idle(aio_worker_t *);
2867c478bd9Sstevel@tonic-gate extern void *_aio_do_request(void *);
28734709573Sraf extern void *_aio_do_notify(void *);
28834709573Sraf extern void _lio_remove(aio_req_t *);
2897c478bd9Sstevel@tonic-gate extern aio_req_t *_aio_req_remove(aio_req_t *);
29034709573Sraf extern int _aio_get_timedelta(timespec_t *, timespec_t *);
29134709573Sraf extern aio_result_t *_aio_req_done(void);
29234709573Sraf extern void _aio_set_result(aio_req_t *, ssize_t, int);
293*f841f6adSraf extern int _aio_sigev_thread_init(struct sigevent *);
294*f841f6adSraf extern int _aio_sigev_thread(aiocb_t *);
295*f841f6adSraf #if !defined(_LP64)
296*f841f6adSraf extern int _aio_sigev_thread64(aiocb64_t *);
297*f841f6adSraf #endif
29834709573Sraf 
29934709573Sraf extern aio_worker_t *_kaiowp;		/* points to kaio cleanup thread */
30034709573Sraf extern aio_worker_t *__workers_rw;	/* list of all rw workers */
30134709573Sraf extern aio_worker_t *__nextworker_rw;	/* worker chosen for next rw request */
30234709573Sraf extern int __rw_workerscnt;		/* number of rw workers */
30334709573Sraf extern aio_worker_t *__workers_no;	/* list of all notification workers */
30434709573Sraf extern aio_worker_t *__nextworker_no;	/* worker chosen, next notification */
30534709573Sraf extern int __no_workerscnt;		/* number of notification workers */
30634709573Sraf extern mutex_t __aio_initlock;		/* makes aio initialization atomic */
307*f841f6adSraf extern cond_t __aio_initcv;
308*f841f6adSraf extern int __aio_initbusy;
30934709573Sraf extern mutex_t __aio_mutex;		/* global aio lock */
31034709573Sraf extern cond_t _aio_iowait_cv;		/* wait for userland I/Os */
31134709573Sraf extern cond_t _aio_waitn_cv;		/* wait for end of aio_waitn */
3127c478bd9Sstevel@tonic-gate extern int _max_workers;		/* max number of workers permitted */
3137c478bd9Sstevel@tonic-gate extern int _min_workers;		/* min number of workers */
3147c478bd9Sstevel@tonic-gate extern sigset_t _worker_set;		/* worker's signal mask */
3157c478bd9Sstevel@tonic-gate extern int _aio_worker_cnt;		/* number of AIO workers */
3167c478bd9Sstevel@tonic-gate extern int _sigio_enabled;		/* when set, send SIGIO signal */
3177c478bd9Sstevel@tonic-gate extern pid_t __pid;			/* process's PID */
31834709573Sraf extern int __uaio_ok;			/* indicates if aio is initialized */
3197c478bd9Sstevel@tonic-gate extern int _kaio_ok;			/* indicates if kaio is initialized */
32034709573Sraf extern pthread_key_t _aio_key;		/* for thread-specific data */
32134709573Sraf extern aio_req_t *_aio_done_tail;	/* list of done requests */
32234709573Sraf extern aio_req_t *_aio_done_head;
32334709573Sraf extern aio_req_t *_aio_doneq;
32434709573Sraf extern int _aio_freelist_cnt;
32534709573Sraf extern int _aio_allocated_cnt;
32634709573Sraf extern int _aio_donecnt;
32734709573Sraf extern int _aio_doneq_cnt;
32834709573Sraf extern int _aio_waitncnt;		/* # of requests for aio_waitn */
32934709573Sraf extern int _aio_outstand_cnt;		/* # of outstanding requests */
33034709573Sraf extern int _kaio_outstand_cnt;		/* # of outstanding kaio requests */
33134709573Sraf extern int _aio_req_done_cnt;		/* req. done but not in "done queue" */
33234709573Sraf extern int _aio_kernel_suspend;		/* active kernel kaio calls */
33334709573Sraf extern int _aio_suscv_cnt;		/* aio_suspend calls waiting on cv's */
33434709573Sraf extern int _aiowait_flag;		/* when set, aiowait() is inprogress */
335*f841f6adSraf extern int _aio_flags;			/* see defines, above */
33634709573Sraf extern uint32_t *_kaio_supported;
3377c478bd9Sstevel@tonic-gate 
338*f841f6adSraf extern const sigset_t maskset;		/* all maskable signals */
339*f841f6adSraf 
3407c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
3417c478bd9Sstevel@tonic-gate }
3427c478bd9Sstevel@tonic-gate #endif
3437c478bd9Sstevel@tonic-gate 
344*f841f6adSraf #endif	/* _ASYNCIO_H */
345