Un poco de ensamblaje
Después de leer este artículo acerca de tampones de bloqueo libres y viendo el uso de CAS (comparar e intercambiar), me sentí como publicar el código en ensamblador para hacer lo mismo. El caso 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 que
. En primer lugar es para el CAS y el segundo es para la informática GCD utilizando el algoritmo de Euclides (éste se puede encontrar en muchos lugares y tutoriales, así).
Compila y ejecuta las instrucciones de gcc file_name.c ; ./a.out
Compara y Swap
# Include# Include / / Cambio - nuevovalor, comperand es viejo / valor esperado / * * Función que realmente hace lo siguiente - si el valor en * dest es igual a oldValue continuación, sustituirla por otra nuevovalor dejarlo como está: hacer todo esto de forma atómica * * Hay dos opciones para el valor de retorno * El valor inicial de 1.is * dest y dejar la carga de la FXN llamando al compararlo con OLDVAL * 2. hacerlo aquí y devolver 0 o 1, esto debe ser más eficiente ** / / * Después se convertirá 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 nuevovalor, int oldValue) {* / int resultado = 1 ;/ * 1 muestra que el CAS tuvo éxito y 0 muestra que fallaron * / / * Por cierto necesidad de establecer cc para vapulear la bandera! * / __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" / * debe de cierre puede ser en la misma línea * / "HECHO jz \ n \ t" "Movl $ 0,% 1 \ n \ t" "HECHO: \ n \ t" : "= M" (destino), "= g" (resultado) : "G" (oldValue), "g" (nuevo_valor), "m" (destino) : "% 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 ("valor de cambio 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 mediante el 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 primer segundo,; printf ("Introduzca dos enteros:"); scanf ("% d% d", y en primer lugar, y segundo); printf ("El MCD de% d &% d es% d \ n", primero, segundo, mcd (primero, segundo)); return 0; }



































