xref: /titanic_52/usr/src/uts/common/io/nge/nge_atomic.c (revision 75d94465dbafa487b716482dc36d5150a4ec9853)
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
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
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
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