16f3e57acSmx205022 /*
247693af9Smx205022 * CDDL HEADER START
347693af9Smx205022 *
447693af9Smx205022 * The contents of this file are subject to the terms of the
547693af9Smx205022 * Common Development and Distribution License (the "License").
647693af9Smx205022 * You may not use this file except in compliance with the License.
747693af9Smx205022 *
847693af9Smx205022 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
947693af9Smx205022 * or http://www.opensolaris.org/os/licensing.
1047693af9Smx205022 * See the License for the specific language governing permissions
1147693af9Smx205022 * and limitations under the License.
1247693af9Smx205022 *
1347693af9Smx205022 * When distributing Covered Code, include this CDDL HEADER in each
1447693af9Smx205022 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1547693af9Smx205022 * If applicable, add the following below this CDDL HEADER, with the
1647693af9Smx205022 * fields enclosed by brackets "[]" replaced with your own identifying
1747693af9Smx205022 * information: Portions Copyright [yyyy] [name of copyright owner]
1847693af9Smx205022 *
1947693af9Smx205022 * CDDL HEADER END
206f3e57acSmx205022 */
216f3e57acSmx205022
226f3e57acSmx205022 /*
2347693af9Smx205022 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
2447693af9Smx205022 * Use is subject to license terms.
256f3e57acSmx205022 */
266f3e57acSmx205022
276f3e57acSmx205022 #include "nge.h"
286f3e57acSmx205022
296f3e57acSmx205022 /*
306f3e57acSmx205022 * Atomically decrement a counter, but only if it will remain
316f3e57acSmx205022 * positive (>=0) afterwards.
326f3e57acSmx205022 */
336f3e57acSmx205022 boolean_t
nge_atomic_decrease(uint64_t * count_p,uint64_t n)346f3e57acSmx205022 nge_atomic_decrease(uint64_t *count_p, uint64_t n)
356f3e57acSmx205022 {
366f3e57acSmx205022 uint64_t oldval;
376f3e57acSmx205022 uint64_t newval;
386f3e57acSmx205022
396f3e57acSmx205022 /* ATOMICALLY */
406f3e57acSmx205022 do {
416f3e57acSmx205022 oldval = *count_p;
426f3e57acSmx205022 newval = oldval - n;
436f3e57acSmx205022 if (oldval < n)
446f3e57acSmx205022 return (B_FALSE);
45*75d94465SJosef 'Jeff' Sipek } while (atomic_cas_64(count_p, oldval, newval) != oldval);
466f3e57acSmx205022
476f3e57acSmx205022 return (B_TRUE);
486f3e57acSmx205022 }
496f3e57acSmx205022
506f3e57acSmx205022 /*
516f3e57acSmx205022 * Atomically increment a counter
526f3e57acSmx205022 */
536f3e57acSmx205022 void
nge_atomic_increase(uint64_t * count_p,uint64_t n)546f3e57acSmx205022 nge_atomic_increase(uint64_t *count_p, uint64_t n)
556f3e57acSmx205022 {
566f3e57acSmx205022 uint64_t oldval;
576f3e57acSmx205022 uint64_t newval;
586f3e57acSmx205022
596f3e57acSmx205022 /* ATOMICALLY */
606f3e57acSmx205022 do {
616f3e57acSmx205022 oldval = *count_p;
626f3e57acSmx205022 newval = oldval + n;
63*75d94465SJosef 'Jeff' Sipek } while (atomic_cas_64(count_p, oldval, newval) != oldval);
646f3e57acSmx205022 }
656f3e57acSmx205022
666f3e57acSmx205022
676f3e57acSmx205022 /*
686f3e57acSmx205022 * Atomically shift a 32-bit word left, returning
696f3e57acSmx205022 * the value it had *before* the shift was applied
706f3e57acSmx205022 */
716f3e57acSmx205022 uint32_t
nge_atomic_shl32(uint32_t * sp,uint_t count)726f3e57acSmx205022 nge_atomic_shl32(uint32_t *sp, uint_t count)
736f3e57acSmx205022 {
746f3e57acSmx205022 uint32_t oldval;
756f3e57acSmx205022 uint32_t newval;
766f3e57acSmx205022
776f3e57acSmx205022 /* ATOMICALLY */
786f3e57acSmx205022 do {
796f3e57acSmx205022 oldval = *sp;
806f3e57acSmx205022 newval = oldval << count;
81*75d94465SJosef 'Jeff' Sipek } while (atomic_cas_32(sp, oldval, newval) != oldval);
826f3e57acSmx205022
836f3e57acSmx205022 return (oldval);
846f3e57acSmx205022 }
85