Coherent4.2.10/include/kernel/v_proc.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_V_PROC_H__
#define	__KERNEL_V_PROC_H__

/*
 * This function describes a high-level abstract interface to the low-level
 * scheduling system that is suitable for multiprocessor use. The design of
 * this interface has been primarily motivated by the multiprocessor DDI/DKI
 * sleep lock and synchronization variable functions, which impose a rather
 * different model of sleep incompatible with the old-style sleep () and
 * wakeup () functions. See "ksynch.c" for a detailed discussion of this.
 *
 * This interface is private to this DDI/DKI implementation, and is not
 * part of the DDI/DKI itself. Portable code should not rely on the contents
 * of this header at all.
 */

#include <common/ccompat.h>
#include <kernel/_sleep.h>
#include <kernel/ddi_proc.h>


/*
 * Flag values to pass to MAKE_SLEEPING ().
 */

enum {
	SLEEP_NO_SIGNALS,
	SLEEP_INTERRUPTIBLE
};


/*
 * The following structure type defines the information that a client of
 * MAKE_SLEEPING is required to keep.
 *
 * If the underlying implementation uses an adress-based hash-list like the
 * old-style sleep () and wakeup () functions, then this item need not contain
 * any data. However, making at least one byte in size gives the property that
 * the address of such an item is unique. While this would normally contain
 * pointers threading process-table entries together, an implementation based
 * on old-style broadcast wakeup is plausible (where this structure would
 * contain counters to implement the one-at-a-time wakeup).
 *
 * Since this stuff is used to implement sleep locking, it is justified in not
 * using basic locks but going instead to the really primitive operations.
 */

typedef struct proc_list plist_t;

struct proc_list {
	atomic_uchar_t	pl_locked;	/* control list manipulation */
	pnode_t	      *	pl_head;	/* first waiting process info */
};


#define	PLIST_INIT(l)		((l)->pl_head = NULL, \
				 (void) ATOMIC_CLEAR_UCHAR ((l)->pl_locked))
#define PLIST_DESTROY(l)	((void) 0)
#define PLIST_LOCK(l,n)		(TEST_AND_SET_LOCK ((l)->pl_locked, plhi, \
						    (n)))
#define	PLIST_UNLOCK(l,p)	(ATOMIC_CLEAR_UCHAR ((l)->pl_locked), \
						     (void) splx (p))
#define	PLIST_ASSERT_LOCKED(l)	ASSERT (ATOMIC_FETCH_UCHAR ((l)->pl_locked) \
					!= 0)


/*
 * External function definitions. The curious may like to note that the use
 * of the __PROTO () macro below has a useful side-effect with respect to
 * macro-expansion of MAKE_SLEEPING (). The ISO C preprocessor scanning rules
 * prevent MAKE_SLEEPING () below from being expanded because the next right
 * token is not a left parenthesis. The rescanning rules mean that even through
 * __PROTO () actually expands to something beginning with a left parenthesis,
 * the MAKE_SLEEPING token will get copied to the output without expansion,
 * because it will not be considered again.
 *
 * This feature may be of some use if one has a non-ISO C compiler but can
 * get the source ISO-preprocessed. Many K&R compilers do not understand the
 * ISO macro-suppression idiom of enclosing a macro name within parentheses
 * (this suppresses macro-expansion because the next token will be a right
 * parenthesis) in function declarations due to weaknesses in the grammars
 * used. Use of an identity macro to enclose the parameter list ensures that
 * the preprocessor doesn't perform the expansion but leaves the function
 * name unadorned by unnecessary parentheses. Note that enclosing the function
 * name does not have the suppressing effect!
 */

__EXTERN_C_BEGIN__

__sleep_t	MAKE_SLEEPING	__PROTO ((plist_t * _plistp, int _priority,
					  int _flag));
void		RUN_NEXT	__PROTO ((void));
__VOID__      *	WAKE_ONE	__PROTO ((plist_t * _plistp));
void		WAKE_ALL	__PROTO ((plist_t * _plistp));

__VOID__      *	PROC_HANDLE	__PROTO ((void));

__EXTERN_C_END__


#endif	/* ! defined (__KERNEL_V_PROC_H__) */