win-pvdrivers

view liblfds.6/src/single_dir_for_windows_kernel/abstraction_increment.c @ 1025:aa2e51f67f7c

Fix hibernate under Win8. Change debugprints.
author James Harper <james.harper@bendigoit.com.au>
date Tue Feb 19 15:14:53 2013 +1100 (2013-02-19)
parents 6300617040e0
children
line source
1 #include "abstraction_internal.h"
7 /****************************************************************************/
8 #if (defined _WIN64 && defined _MSC_VER)
10 /* TRD : 64 bit Windows (user-mode or kernel) on any CPU with the Microsoft C compiler
12 _WIN64 indicates 64 bit Windows
13 _MSC_VER indicates Microsoft C compiler
14 */
16 INLINE atom_t abstraction_increment( atom_t *value )
17 {
18 __int64
19 rv;
21 assert( value != NULL );
23 rv = _InterlockedIncrement64( (__int64 *) value );
25 return( (atom_t) rv );
26 }
28 #endif
34 /****************************************************************************/
35 #if (!defined _WIN64 && defined _WIN32 && defined _MSC_VER)
37 /* TRD : 32 bit Windows (user-mode or kernel) on any CPU with the Microsoft C compiler
39 (!defined _WIN64 && defined _WIN32) indicates 32 bit Windows
40 _MSC_VER indicates Microsoft C compiler
41 */
43 INLINE atom_t abstraction_increment( atom_t *value )
44 {
45 long int
46 rv;
48 assert( value != NULL );
50 rv = _InterlockedIncrement( (long int *) value );
52 return( (atom_t) rv );
53 }
55 #endif
61 /****************************************************************************/
62 #if (!defined __arm__ && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1 && __GNUC_PATCHLEVEL__ >= 0)
64 /* TRD : any OS on any CPU with GCC 4.1.0 or better
66 GCC 4.1.0 introduced the __sync_*() atomic intrinsics
68 __GNUC__ / __GNUC_MINOR__ / __GNUC_PATCHLEVEL__ indicates GCC and which version
69 */
71 INLINE atom_t abstraction_increment( atom_t *value )
72 {
73 atom_t
74 rv;
76 assert( value != NULL );
78 // TRD : no need for casting here, GCC has a __sync_add_and_fetch() for all native types
80 rv = __sync_add_and_fetch( value, 1 );
82 return( rv );
83 }
85 #endif
91 /****************************************************************************/
92 #if (defined __arm__ && __GNUC__ >= 4)
94 /* TRD : any OS on any CPU with GCC 4.1.0 or better
96 GCC 4.1.0 introduced the __sync_*() atomic intrinsics
98 __arm__ indicates ARM
99 __GNUC__ indicates GCC
100 */
102 INLINE atom_t abstraction_increment( atom_t *value )
103 {
104 atom_t
105 stored_flag = 0,
106 new_value = 0;
108 assert( value != NULL );
110 __asm__ __volatile__
111 (
112 " mov %[stored_flag], #1;" // move 1 into stored_flag
113 " mcr p15, 0, %[zero], c7, c10, 5;" // memory barrier (ARM v6 compatible)
114 "atomic_add:;"
115 " ldrex %[new_value], [%[value]]; " // load *value into new_value
116 " add %[new_value], #1;" // add 1 to new_value
117 " strex %[stored_flag], %[new_value], [%[value]];" // try to store new_value into *value (on success, strex puts 0 into stored_flag)
118 " teq %[stored_flag], #0;" // check if stored_flag is 0
119 " bne atomic_add;" // if not 0, retry (someone else touched *value after we loaded but before we stored)
120 " mcr p15, 0, %[zero], c7, c10, 5;" // memory barrier (ARM v6 compatible)
122 // output
123 : "+m" (*value), [new_value] "+&r" (new_value), [stored_flag] "+&r" (stored_flag)
125 // input
126 : [value] "r" (value), [zero] "r" (0)
128 // clobbered
129 : "cc", "memory" // memory is clobbered because we issue a memory barrier
130 );
132 return( new_value );
133 }
135 #endif