Home | History | Annotate | Line # | Download | only in sys
      1 /*	$NetBSD: psref.h,v 1.4 2019/05/17 03:34:27 ozaki-r Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2016 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Taylor R. Campbell.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #ifndef	_SYS_PSREF_H
     33 #define	_SYS_PSREF_H
     34 
     35 #ifdef _KERNEL_OPT
     36 #include "opt_psref_debug.h"
     37 #endif
     38 
     39 #include <sys/types.h>
     40 #include <sys/queue.h>
     41 
     42 struct cpu_info;
     43 struct lwp;
     44 
     45 struct psref;
     46 struct psref_class;
     47 struct psref_target;
     48 
     49 /*
     50  * struct psref_target
     51  *
     52  *	Bookkeeping for an object to which users can acquire passive
     53  *	references.  This is compact so that it can easily be embedded
     54  *	into many multitudes of objects, e.g. IP packet flows.
     55  *
     56  *	prt_draining is false on initialization, and may be written
     57  *	only once, to make it true, when someone has prevented new
     58  *	references from being created and wants to drain the target in
     59  *	order to destroy it.
     60  */
     61 struct psref_target {
     62 	struct psref_class	*prt_class;
     63 	bool			prt_draining;
     64 };
     65 
     66 /*
     67  * struct psref
     68  *
     69  *	Bookkeeping for a single passive reference.  There should only
     70  *	be a few of these per CPU in the system at once, no matter how
     71  *	many targets are stored, so these are a bit larger than struct
     72  *	psref_target.  The contents of struct psref may be read and
     73  *	written only on the local CPU.
     74  */
     75 struct psref {
     76 	SLIST_ENTRY(psref)		psref_entry;
     77 	void				*psref_debug; /* For debugging */
     78 	const struct psref_target	*psref_target;
     79 	struct lwp			*psref_lwp;
     80 	struct cpu_info			*psref_cpu;
     81 };
     82 
     83 #ifdef _KERNEL
     84 void	psref_init(void);
     85 
     86 struct psref_class *
     87 	psref_class_create(const char *, int);
     88 void	psref_class_destroy(struct psref_class *);
     89 
     90 void	psref_target_init(struct psref_target *, struct psref_class *);
     91 void	psref_target_destroy(struct psref_target *, struct psref_class *);
     92 
     93 void	psref_acquire(struct psref *, const struct psref_target *,
     94 	    struct psref_class *);
     95 void	psref_release(struct psref *, const struct psref_target *,
     96 	    struct psref_class *);
     97 void	psref_copy(struct psref *, const struct psref *,
     98 	    struct psref_class *);
     99 
    100 /* For use only in assertions.  */
    101 bool	psref_held(const struct psref_target *, struct psref_class *);
    102 
    103 
    104 #ifdef PSREF_DEBUG
    105 void	psref_debug_barrier(void);
    106 void	psref_debug_init_lwp(struct lwp *);
    107 
    108 #define PSREF_DEBUG_BARRIER()		psref_debug_barrier()
    109 #define PSREF_DEBUG_INIT_LWP(l)		psref_debug_init_lwp((l))
    110 #define PSREF_DEBUG_FILL_RETURN_ADDRESS0(psref, addr)	do {		\
    111 	(psref)->psref_debug = (addr);					\
    112 } while (0)
    113 #define PSREF_DEBUG_FILL_RETURN_ADDRESS(psref)	do {			\
    114 	PSREF_DEBUG_FILL_RETURN_ADDRESS0(psref, __builtin_return_address(0));\
    115 } while (0)
    116 
    117 #else
    118 
    119 #define PSREF_DEBUG_BARRIER()		__nothing
    120 #define PSREF_DEBUG_INIT_LWP(l)		__nothing
    121 #define PSREF_DEBUG_FILL_RETURN_ADDRESS0(psref, addr)	__nothing
    122 #define PSREF_DEBUG_FILL_RETURN_ADDRESS(psref)		__nothing
    123 
    124 #endif /* PSREF_DEBUG */
    125 
    126 #endif /* _KERNEL */
    127 
    128 #endif	/* _SYS_PSREF_H */
    129