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