Lite av enheten
Efter att ha läst den här artikeln om Lock gratis buffertar och ser användning av CAS (jämför och swap), kände jag mig som att publicera den assemblerkod att göra detsamma. Använd fall över det var att skriva en alternativ metod och kallar det från Java (tillbaka i 1,5, då samtidiga datastrukturer i Java var mer eller mindre obefintlig). Utan vidare, jag släppa loss koden på dig
. Första är för CAS och andra är för beräkning GCD använda Euklides algoritm (detta kan hittas på många ställen och handledning samt).
Kompilera och köra instruktionerna gcc file_name.c ; ./a.out
Jämför och Swap
# Include# Include / / Exchange - newValue är comperand gamla / förväntat värde / * * Funktion faktiskt gör följande sak - om värdet på * dest är lika med oldvalue sedan ersätta den med newValue annars lämna den oförändrad: inte alla dessa Atomically * * Det finns två alternativ för returvärde * 1.is initiala värdet av * dest och lämna bördan att kalla fxn att jämföra den med oldval * 2. gör det hit och returnera 0 eller 1, bör detta vara effektivare ** / / * Senare ändrar det till makro * / int cas (int * dest, int oldvalue, int newValue) { printf ("(% d,% d,% d)", * DEST, oldvalue, newValue); / * Int CAS (int dest, int oldvalue, int newValue) {* / / * Int CAS (int dest, int newValue, int oldvalue) {* / int result = 1 ;/ * 1 visar att CAS lyckades och 0 visar att det misslyckades * / / * BTW behöver sätta cc för flagga dunkardags! * / __asm__ __ volatile__ ( "MOVL% 2,%% EAX \ n \ t" "MOVL% 3,%% EBX \ n \ t" "MOVL% 0,%% ECX \ n \ t" "LOCK \ n \ t" "CMPXCHG EBX%% (%% ECX) \ n \ t" / * bör låset på samma linje * / "JZ görs \ n \ t" "MOVL $ 0,% 1 \ n \ t" "KLART: \ n \ t" : "= M" (DEST), "= g" (resultat) : "G" (oldvalue), "g" (newValue), "m" (dest) : "% EAX", "% ebx", "ECX", "CC" ); printf ("(% d,% d,% d)", * DEST, oldvalue, newValue); RETURN RESULT; } / * TODO * Skriva en annan asm fxn som sätter ovan fxn i en while-slinga och fortsätta att försöka om det inte lyckas * / int main () { int en = 5, b = 6; int * c = (int *) malloc (sizeof (int)); * C = 6; / * Int c = 6, * / printf ("% d \ n", CAS (c, b, b)); printf ("% d \ n", CAS (c, b, a)); printf ("% d \ n", CAS (c, a, a)); printf ("% d \ n", CAS (c, b, b)); * C = 6; / * C = 5, * / printf ("ändra värdet * c till% d \ n", * c); printf ("% d \ n", CAS (c, b, b)); printf ("% d \ n", CAS (c, b, a)); printf ("% d \ n", CAS (c, a, a)); printf ("% d \ n", CAS (c, a, b)); printf ("% d \ n", CAS (c, b, a)); returnera 0; }
Formatera anteckningar - verkar som att WP syntax highlighter är att lägga till i slutändan, ignorera det.
GCD
# Includeint gcd (int a, int b) { int resultat; / * Beräkna största gemensamma nämnaren att använda Euklides algoritm * / __asm__ __ volatile__ ("MOVL% 1,%% EAX," "MOVL% 2,%% EBX;" "Forts: cMpl 0 $,%% EBX;" "Je KLAR;" "Xorl%% EDX,%% EDX," "Idivl%% EBX;" "MOVL%% EBX,%% EAX," "MOVL%% EDX,%% EBX;" "JMP forts," "KLAR: MOVL%% EAX,% 0;" "= g" (Resultat): "g" (en), "g" (b) ); RETURN RESULT; } int main () { int första, andra; printf ("Ange två heltal:"); scanf ("% d% d", & första, och andra); printf ("GCD av% d &% d är% d \ n" första, andra, gcd (första, andra)); returnera 0; }



































