xref: /titanic_44/usr/src/uts/common/io/nge/nge_atomic.c (revision 2a9459bdd821c1cf59590a7a9069ac9c591e8a6b)
1 /*
2  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 /*
7  * This file may contain confidential information of Nvidia
8  * and should not be distributed in source form without approval
9  * from Sun Legal.
10  */
11 
12 #pragma ident	"%Z%%M%	%I%	%E% SMI"
13 
14 #include "nge.h"
15 
16 /*
17  * Atomically decrement a counter, but only if it will remain
18  * positive (>=0) afterwards.
19  */
20 boolean_t
21 nge_atomic_decrease(uint64_t *count_p, uint64_t n)
22 {
23 	uint64_t oldval;
24 	uint64_t newval;
25 
26 	/* ATOMICALLY */
27 	do {
28 		oldval = *count_p;
29 		newval = oldval - n;
30 		if (oldval < n)
31 			return (B_FALSE);
32 	} while (cas64(count_p, oldval, newval) != oldval);
33 
34 	return (B_TRUE);
35 }
36 
37 /*
38  * Atomically increment a counter
39  */
40 void
41 nge_atomic_increase(uint64_t *count_p, uint64_t n)
42 {
43 	uint64_t oldval;
44 	uint64_t newval;
45 
46 	/* ATOMICALLY */
47 	do {
48 		oldval = *count_p;
49 		newval = oldval + n;
50 	} while (cas64(count_p, oldval, newval) != oldval);
51 }
52 
53 
54 /*
55  * Atomically shift a 32-bit word left, returning
56  * the value it had *before* the shift was applied
57  */
58 uint32_t
59 nge_atomic_shl32(uint32_t *sp, uint_t count)
60 {
61 	uint32_t oldval;
62 	uint32_t newval;
63 
64 	/* ATOMICALLY */
65 	do {
66 		oldval = *sp;
67 		newval = oldval << count;
68 	} while (cas32(sp, oldval, newval) != oldval);
69 
70 	return (oldval);
71 }
72