/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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
* 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 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright 2015, Joyent, Inc.
*/
#ifndef _SYS_POLL_IMPL_H
#define _SYS_POLL_IMPL_H
/*
* Caching Poll Subsystem:
*
* Each kernel thread (1), if engaged in poll system call, has a reference to
* a pollstate_t (2), which contains relevant flags and locks. The pollstate_t
* contains a pointer to a pollcache_t (3), which caches the state of previous
* calls to poll. A bitmap (4) is stored inside the poll cache, where each
* bit represents a file descriptor. The bits are set if the corresponding
* device has a polled event pending. Only fds with their bit set will be
* examined on the next poll invocation. The pollstate_t also contains a list
* of fd sets (5), which are represented by the pollcacheset_t type. These
* structures keep track of the pollfd_t arrays (6) passed in from userland.
* Each polled file descriptor has a corresponding polldat_t which can be
* chained onto a device's pollhead, and these are kept in a hash table (7)
* inside the pollcache_t. The hash table allows efficient conversion of a
* given fd to its corresponding polldat_t.
*
* (1) (2)
* +-----------+ +-------------+
* | kthread_t |--->| pollstate_t |-->+-------------+ (6)
* +-----------+ +-------------+(5)| pcacheset_t |->[_][_][_][_] pollfd_t
* | +-------------+
* | | pcacheset_t |->[_][_][_][_] pollfd_t
* (1a) | +-------------+
* +---------------+ |
* +-v-------------+ |
* | |
* +------------------+ |
* (7) (3) V v
* polldat hash +-------------+ (4) bitmap representing fd space
* [_][_][_][_]<----| |--->000010010010001010101010101010110
* | | | | | pollcache_t |
* . v . . | |
* [polldat_t] +-------------+
* |
* [polldat_t]
* |
* v
* NULL
*
*
* definition and the routines managing the structure. But poll(2) and
* table (1a) contains an array of pointers, each pointing at a pollcache_t
* struct (3). A device minor number is used as an device table index.
*
*/
#include <sys/port_kernel.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Typedefs
*/
struct pollcache;
struct pollstate;
struct pcachelink;
struct polldat;
/*
* description of pollcacheset structure
*/
typedef struct pollcacheset {
/*
* Maximum depth for recusive poll operations.
*/
/*
* State information kept by each polling thread
*/
struct pollstate {
};
/* pollstate flags */
/* pollstate_enter results */
#define PSE_SUCCESS 0
/*
* poll cache size defines
*/
/*
* poll.c assumes the POLLMAPCHUNK is power of 2
*/
/*
* used to refrence from watched fd back to the fd position in cached
* poll list for quick revents update.
*/
typedef struct xref {
} xref_t;
typedef enum pclstate {
} pclstate_t;
/*
* The pcachelink struct creates an association between parent and child
* pcl_lock although manipulation of pcl_child_next or pcl_parent_next also
* requires holding pc_lock in the respective pcl_parent_pc or pcl_child_pc
* pollcache.
*/
struct pcachelink {
};
/*
* polldat is an entry for a cached poll fd. A polldat struct can be in
* poll cache table as well as on pollhead ph_list, which is used by
* pollwakeup to wake up a sleeping poller. There should be one polldat
* per polled fd hanging off pollstate struct.
*/
struct polldat {
};
/*
* One cache for each thread that polls. Points to a bitmap (used by pollwakeup)
* and a hash table of polldats.
* The offset of pc_lock field must be kept in sync with the pc_lock offset
* of port_fdcache_t, both structs implement pc_lock with offset 0 (see also
* pollrelock()).
*/
struct pollcache {
};
/* pc_flag */
#if defined(_KERNEL)
/*
* Internal routines.
*/
extern void pollnotify(pollcache_t *, int);
/*
* public poll head interfaces (see poll.h):
*
* pollhead_clean clean up all polldats on a pollhead list
*/
extern void pollhead_clean(pollhead_t *);
/*
* private poll head interfaces:
*
* pollhead_insert adds a polldat to a pollhead list
* pollhead_delete removes a polldat from a pollhead list
*/
/*
* poll state interfaces:
*
* pollstate_create initializes per-thread pollstate
* pollstate_destroy cleans up per-thread pollstate
* pollstate_enter safely lock pollcache for pollstate
* pollstate_exit unlock pollcache from pollstate
*/
extern pollstate_t *pollstate_create(void);
extern void pollstate_destroy(pollstate_t *);
extern int pollstate_enter(pollcache_t *);
extern void pollstate_exit(pollcache_t *);
/*
* public pcache interfaces:
*
* pcache_alloc allocate a poll cache skeleton
* pcache_create creates all poll cache supporting data struct
* pcache_insert cache a poll fd, calls pcache_insert_fd
* pcache_lookup given an fd list, returns a cookie
* pcache_poll polls the cache for fd's having events on them
* pcache_clean clean up all the pollhead and fpollinfo reference
* pcache_destroy destroys the pcache
*/
extern pollcache_t *pcache_alloc();
int);
extern void pcache_clean(pollcache_t *);
extern void pcache_destroy(pollcache_t *);
/*
* private pcache interfaces:
*
* pcache_lookup_fd lookup an fd, returns a polldat
* pcache_alloc_fd allocates and returns a polldat
* pcache_insert_fd insert an fd into pcache (called by pcache_insert)
* pcache_delete_fd insert an fd into pcache (called by pcacheset_delete_fd)
* pcache_grow_hashtbl grows the pollcache hash table and rehash
* pcache_grow_map grows the pollcache bitmap
* pcache_update_xref update cross ref (from polldat back to cacheset) info
* pcache_clean_entry cleanup an entry in pcache and more...
* pcache_wake_parents wake linked parent pollcaches
*/
extern polldat_t *pcache_alloc_fd(int);
extern void pcache_grow_map(pollcache_t *, int);
extern void pcache_clean_entry(pollstate_t *, int);
extern void pcache_wake_parents(pollcache_t *);
/*
* pcacheset interfaces:
*
* pcacheset_create creates new pcachesets (easier for dynamic pcachesets)
* pcacheset_destroy destroys a pcacheset
* pcacheset_cache_list caches and polls a new poll list
* pcacheset_remove_list removes (usually a partial) cached poll list
* pcacheset_resolve resolves extant pcacheset and fd list
* pcacheset_cmp compares a pcacheset with an fd list
* pcacheset_invalidate invalidate entries in pcachesets
* pcacheset_reset_count resets the usage counter of pcachesets
* pcacheset_replace selects a poll cacheset for replacement
*/
extern pollcacheset_t *pcacheset_create(int);
extern void pcacheset_destroy(pollcacheset_t *, int);
int);
extern void pcacheset_reset_count(pollstate_t *, int);
extern int pcacheset_replace(pollstate_t *);
#endif /* defined(_KERNEL) */
#ifdef __cplusplus
}
#endif
#endif /* defined(_KERNEL) || defined(_KMEMUSER) */
#endif /* _SYS_POLL_IMPL_H */