Una mica d'acoblament

29 agost 2009 per Prashant · Comentaris
Filed under: la tecnologia

Després de llegir aquest article sobre tampons de bloqueig lliures i veient l'ús de CAS (comparar i intercanviar), em vaig sentir com alliberar el codi en assemblador per fer el mateix. El cas d'ús sobre el que havia d'escriure un mètode natiu i en diuen de Java (de nou en 1,5, quan les estructures de dades concurrents en Java eren més o menys inexistent). Sense més preàmbuls, vaig a alliberar el codi en què :) . En primer lloc és per al CAS i el segon és per a la informàtica GCD utilitzant l'algorisme d'Euclides (aquest es pot trobar a molts llocs i tutorials, així).

Donat les instruccions de gcc file_name.c ; ./a.out

Compara i Swap

   # Include 
  # Include 
 / / Canvi - nuevovalor, comperand és vell / valor esperat
 / *
  * Funció que realment fa el següent - si el valor a * dest és igual a oldValue continuació, substituir-la per una altra nuevovalor deixar-ho com està: fer tot això de forma atòmica
  *
  * Hi ha dues opcions per al valor de retorn
  * El valor inicial de 1.is * dest i deixar la càrrega de la FXN trucant al comparar-lo amb OLDVAL
  * 2.  fer-ho aquí i tornar 0 o 1, això ha de ser més eficient
  ** /

 / * Després es convertirà en macro * /
 ques 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 resultat = 1 ;/ * 1 mostra que el CAS va tenir èxit i 0 mostra que van fallar * /
	 / * Per cert necessitat d'establir cc per apallissar 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" / * ha de tancament pot ser en la mateixa línia * /
			 "FET jz \ n \ t"
			 "Movl $ 0,% 1 \ n \ t"
			 "FET: \ n \ t"
			 : "= M" (destí), "= g" (resultat)
			 : "G" (oldValue), "g" (nuevo_valor), "m" (destí)
			 : "% Eax", "% ebx", "ECX", "CC"
			 );
	 printf ("(% d,% d,% d)", * dest, oldValue, newvalue);
	 return resultat;
 }

 / * TOT
  * Escriure altre FXN asm que posa per sobre de FXN en un bucle while i seguir intentant si no aconsegueix * /

 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 canvi 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;
 }

Notes de format - sembla marcador wp sintaxi és l'addició de al final, ignorar això.

GCD

 # Include 
 int mcd (int a, int b) {
     int resultat;
     / * Calcular màxim comú divisor mitjançant l'algorisme d'Euclides * /
     __asm__ volatile__ __ ("movl% 1,%% eax;"
                           "Movl% 2,%% ebx;"
                           "Cont: CMPL $ 0,%% ebx;"
                           "Je Fet";
                           "Xorl%% EDX,%% EDX;"
                           "Idivl%% ebx;"
                           "Movl% ebx%,%% eax;"
                           "Movl%% EDX, ebx%%;"
                           "JMP cont;"
                           "FET: movl%% eax, 0%;": "= g" (resultat): "g" (a), "g" (b)
     );

     return resultat;
 }

 int main () {
     int primer segon,;
     printf ("Introduïu dos enters:");
     scanf ("% d% d", i en primer lloc, i segon);

     printf ("El MCD de% d &% d és% d \ n", primer, segon, mcd (primer, segon));

     return 0;
 }