Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/external/bsd/drm2/include/linux/kref.h,v rcsdiff: /ftp/cvs/cvsroot/src/sys/external/bsd/drm2/include/linux/kref.h,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.1 retrieving revision 1.2 diff -u -p -r1.1 -r1.2 --- src/sys/external/bsd/drm2/include/linux/kref.h 2013/07/24 00:33:12 1.1 +++ src/sys/external/bsd/drm2/include/linux/kref.h 2014/03/18 18:20:43 1.2 @@ -0,0 +1,111 @@ +/* $NetBSD: kref.h,v 1.2 2014/03/18 18:20:43 riastradh Exp $ */ + +/*- + * Copyright (c) 2013 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Taylor R. Campbell. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LINUX_KREF_H_ +#define _LINUX_KREF_H_ + +#include +#include +#include + +#include + +struct kref { + unsigned int kr_count; +}; + +static inline void +kref_init(struct kref *kref) +{ + kref->kr_count = 1; +} + +static inline void +kref_get(struct kref *kref) +{ + const unsigned int count __unused = + atomic_inc_uint_nv(&kref->kr_count); + + KASSERTMSG((count > 1), "getting released kref"); +} + +static inline int +kref_sub(struct kref *kref, unsigned int count, void (*release)(struct kref *)) +{ + unsigned int old, new; + + do { + old = kref->kr_count; + KASSERTMSG((count <= old), "overreleasing kref: %u - %u", + old, count); + new = (old - count); + } while (atomic_cas_uint(&kref->kr_count, old, new) != old); + + if (new == 0) { + (*release)(kref); + return 1; + } + + return 0; +} + +static inline int +kref_put(struct kref *kref, void (*release)(struct kref *)) +{ + + return kref_sub(kref, 1, release); +} + +static inline int +kref_put_mutex(struct kref *kref, void (*release)(struct kref *), + struct mutex *interlock) +{ + unsigned int old, new; + + do { + old = kref->kr_count; + KASSERT(old > 0); + if (old == 1) { + mutex_lock(interlock); + if (atomic_add_int_nv(&kref->kr_count, -1) == 0) { + (*release)(kref); + return 1; + } + mutex_unlock(interlock); + return 0; + } + new = (old - 1); + } while (atomic_cas_uint(&kref->kr_count, old, new) != old); + + return 0; +} + +#endif /* _LINUX_KREF_H_ */