Coherent4.2.10/include/kernel/ddi_data.h

/* (-lgl
 *	Coherent 386 release 4.2
 *	Copyright (c) 1982, 1993 by Mark Williams Company.
 *	All rights reserved. May not be copied without permission.
 *	For copying permission and licensing info, write licensing@mwc.com
 -lgl) */

#ifndef	__KERNEL_DDI_DATA_H__
#define	__KERNEL_DDI_DATA_H__

/*
 * This internal header contains data definitions common to several of the
 * <sys/ddi...> family of header files. This commonality does not warrant a
 * separate header for each type, because these are normally incomplete types
 * anyway, and the <sys/ddi...> mechanisms are only for internal use.
 */

#include <kernel/_defer.h>
#include <kernel/_lock.h>
#include <kernel/x86lock.h>


/*
 * Defer tables operate at both the per-CPU and global levels.  This is the
 * type of a defer table, and the type used to index the table for reading
 * and writing.
 *
 * The defer tables use short atomic indices because that is considerably
 * simpler and more portable than dealing with atomic pointer types (as they
 * are implemented in this system, anyway).  The extra scaling operation to
 * index the table seems worth it, since it's cheap and for many common CPUs
 * is available as an address mode anyway.
 */

typedef	atomic_uchar_t	deftabidx_t;

/*
 * The per-CPU defer-function tables need locks for writing because they are
 * used to bind routines to specific processors.  The global defer-function
 * tables need read and write locks. The read lock is typically a simple test-
 * and-set lock because the table is tested on the way out of interrupts and
 * we are concerned about the overhead this imposes.
 */

typedef	atomic_uchar_t	defrlock_t;
typedef	__lock_t      *	defwlock_t;

/*
 * The deferred-operation tables come in separate per-CPU and global flavors
 * due to different locking requirements.  In addition, deferred operations
 * can run at different priority levels, most easily managed by having separate
 * tables.
 *
 * One priority level has operations indended to be lower than any interrupt
 * but higher than regular kernel processing. Kernel timeouts are a good
 * example of this. The other priority level has operations that are lower
 * than any kernel-level operation but higher priority than any user-level
 * operation.
 *
 * Because the only difference between the per-CPU and global tables is the
 * read lock, we can use the same structure for all the deferred functions
 * (the read lock takes no extra space under COFF due to the structure
 * alignment rules).
 */

typedef struct {
	__deffuncp_t  *	df_tab;			/* deferred function table */
	deftabidx_t	df_read;		/* next entry to run */
	deftabidx_t	df_max;			/* number of table entries */
	deftabidx_t	df_write;		/* next entry to write to */
	defrlock_t	df_rlock;		/* lock read from table */
	defwlock_t	df_wlock;		/* lock write to table */
} defer_t;


#endif	/* ! defined (__KERNEL_DDI_DATA_H__) */