Un poco de asamblea
Después de leer este artículo acerca de tampones de bloqueo libre y viendo el uso de CAS (compare y swap), me sentí como publicar el código en ensamblador para hacer lo mismo. De casos de uso sobre lo que había que escribir un método nativo y lo llaman de Java (de nuevo en 1,5, cuando las estructuras de datos concurrentes en Java eran más o menos inexistente). Sin más preámbulos, voy a liberar el código en el que
. En primer lugar es para el CAS y la segunda es para calcular mcd usando el algoritmo de Euclides (éste se puede encontrar en muchos lugares y tutoriales también).
Compilar y ejecutar las instrucciones de gcc file_name.c ; ./a.out
Comparar y de intercambio
# Include# Include / / Cambio - nuevo_valor, comperand es viejo / valor esperado / * * Función que realmente hace lo siguiente - si el valor en * dest es igual a oldValue luego reemplazarlo por otro nuevo_valor dejarlo como está: hacer todo esto de forma atómica * * Hay dos opciones para el valor de retorno * 1.is valor inicial de * dest y dejar la carga de llamar a FXN para compararlo con OLDVAL * 2. hacerlo por aquí y devuelve 0 o 1, esto debe ser más eficiente * * / / * Después se transforman en macro * / cas int (int * dest, int oldValue, int nuevo_valor) { printf ("% (d,% d,% d)", * dest, oldValue, newvalue); / * Int cas (int dest, int oldValue, int nuevo_valor) {* / / * Int cas (int dest, int nuevo_valor, int oldValue) {* / int resultado = 1 / * 1 muestra que el CAS tuvo éxito y muestra 0 que no * / / * Por cierto necesidad de establecer cc por la bandera de vapulear! * / __asm__ __volatile__ ( "Movl% 2,%% eax \ n \ t" "Movl% 3%,% ebx \ n \ t" "0% movl%,% ecx \ n \ t" "LOCK \ n \ t" "CMPXCHG ebx%%, (%% ecx) \ n \ t" / * se debe bloquear en la misma línea * / "HECHO jz \ n \ t" "Movl $ 0,% 1 \ n \ t" "HECHO: \ n \ t" : "= M" (dest), "= g" (resultado) : "G" (oldValue), "g" (nuevo_valor), "m" (dest) : "% Eax", "ebx%", "ecx", "cc" ); printf ("% (d,% d,% d)", * dest, oldValue, newvalue); return resultado; } / * TODO * Escribir otro FXN asm que pone por encima de FXN en un bucle while y seguir intentando si no logra * / int main () { int a = 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 ("cambiar el valor de c * a% 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)); return 0; }
Notas de formato - Parece marcador wp sintaxis es la adición de al final, ignorar eso.
GCD
# Includeint mcd (int a, int b) { int resultado; / * Calcular Máximo Común Divisor con * algoritmo de Euclides / __asm__ __volatile__ ("movl% 1,%% eax;" "Movl% 2,%% ebx;" "Cont: $ CMPL 0,% ebx%;" "Je hecho;" "Xorl%% edx,%% edx;" "Idivl%% ebx;" "Movl% ebx%,%% eax;" "Movl%% edx, ebx%%;" "Jmp cont;" "HECHO: movl%% eax,% 0;": "= g" (resultado): "g" (a), "g" (b) ); return resultado; } int main () { int primero, segundo; printf ("Introduzca dos números enteros:"); scanf ("% d% d", y en primer lugar, y segundo); printf ("MCD de% d +% d es% d \ n", primero, segundo, mcd (primero, segundo)); return 0; }



































