; This contains the CPU-dependant variants of some routines. ; (C) 2005 Andreas Rumpf ; This code was inspired by the Freepascal compiler's sources ; All routines here have the _cdecl calling convention because ; that is the only convention any C compiler supports. \python{ # as usual I use my own preprocessor :-) import os def c(name): if os.name == 'posix': return name else: return "_" + name } segment code global \c{cpu_inc_locked} global \c{cpu_dec_locked} global \c{cpu_lock} global \c{cpu_unlock} \c{cpu_dec_locked}: push ebp mov ebp,esp mov eax,[ebp+8] ; first parameter to function lock dec dword [eax] setz al mov esp,ebp pop ebp ret \c{cpu_inc_locked}: push ebp mov ebp,esp mov eax,[ebp+8] ; first parameter to function lock inc dword [eax] mov esp,ebp pop ebp ret ; This code uses the highest bit of the RC to indicate that the RC is ; locked (spinlock). \c{cpu_lock} push ebp mov ebp, esp mov eax, [ebp+8] ; first parameter to function mov edx, [eax] ; load RC or edx, 0x80000000 ; set highest bit spin: xchg [eax], edx ; atomic instruction! pause ; wait a few cycles and edx, 0x80000000 ; mask highest bit jnz spin mov esp, ebp pop ebp ret \c{cpu_unlock} push ebp mov ebp, esp mov eax, [ebp+8] ; first parameter to function mov edx, [eax] ; load RC and edx, 0x7FFFFFFF ; unset highest bit xchg [eax], edx ; atomic instruction! mov esp, ebp pop ebp ret