Малко на събранията

29 август 2009 г. от Prashant ° Коментари
Пила под: технология

След като прочетете тази статия за свободните буфери заключване и виждаме използването на CAS (сравнете и суап), аз се почувствах като публикуване на събранието код, за да направят същото. Използвайте случай, ей там, е да пишат на родния метод и да го наречем от Java (обратно в 1.5, когато едновременно структури от данни в Java са повече или по-малко несъществуващи). Без повече приказки, аз ще отприщи код върху вас :) . Първата е за CAS и втората е за изчисляване на GCD, използвайки алгоритъм на Евклид (това може да се намери на много места и уроци, както и).

Подготвя и изпълнява инструкции gcc file_name.c ; ./a.out

Сравнете и Разменени

   # Включват 
  # Включват 
 / / Обмен - newvalue, comperand е стар / очакваната стойност
 / *
  * Функция всъщност прави следното нещо - ако стойността, на * кр.точка е равна на oldvalue след това да го замени от newvalue друг и остави без промяна: не всички тези с атомна
  *
  * Има два варианта за връщане стойност
  * 1.is първоначалната стойност на * кр.точка и оставете тежестта на призовавайки fxn да го сравни с oldval
  * 2.  го направя тук и да се върне 0 или 1, това трябва да бъде по-ефикасно
  * * /

 / * По-късно го промени в макро * /
 INT CAS (INT * DEST, вътр oldvalue, вътр newvalue) {
	 printf ("(% г% D,% г)" * DEST, oldvalue, newvalue);
	 / * Int CAS (INT DEST, вътр oldvalue, Int newvalue.) {* /
	 / * Int CAS (INT DEST, вътр newvalue, Int oldvalue.) {* /
	 Int резултат = 1; / * 1 показва, че CAS успя и 0 показва, че тя не * /
	 / * BTW трябва да зададете куб.см. за флаг clobbering!  * /
	 __asm__ __volatile__ (
			 "Movl% 2% EAX \ N \ т"
			 "Movl% 3% ebx \ N \ т"
			 "Movl 0%,% ECX \ N \ т"
			 "LOCK \ N \ т"
			 "CMPXCHG ebx%, (%% ECX) \ N \ т" / * трябва LOCK бъде на една и съща линия * /
			 "JZ DONE \ N \ т"
			 "Movl $ 0,% 1 \ N \ т"
			 "Done: \ N \ т"
			 : "=" (DEST), "= G" (резултат)
			 : "Ж" (oldvalue), "ж" (newvalue), "м" (DEST)
			 : "EAX%", "% ebx", "ECX", "вв"
			 );
	 printf ("(% г% D,% г)" * DEST, oldvalue, newvalue);
	 върне резултат;
 }

 / * TODO
  * Пиша друг ASM fxn, който се поставя над fxn в последно време контур и продължаваме да опитваме, освен ако не успее * /

 INT главната () {
	 Int а = 5, б = 6;
	 Int * C = (INT *) malloc (sizeof (INT));
	 * C = 6;
	 / * Int C = 6; * /
	 printf ("% г \ N", CAS (C, B, б));
	 printf ("% D \ N", CAS (C, B, а));
	 printf ("% D \ N", CAS (в,,));
	 printf ("% г \ N", CAS (C, B, б));
	 * C = 6;
	 / * C = 5 * /
	 printf ("промяна на стойността на * С до% г \ N", в);
	 printf ("% г \ N", CAS (C, B, б));
	 printf ("% D \ N", CAS (C, B, а));
	 printf ("% D \ N", CAS (в,,));
	 printf ("% г \ N", CAS (C, A, B));
	 printf ("% D \ N", CAS (C, B, а));
	 връщането на 0;
 }

Форматиране на бележки - изглежда като маркер WP синтаксис е добавянето в края на краищата, да пренебрегнем факта, че.

GCD

 # Включват 
 INT GCD (INT един, вътр б) {
     Int резултат;
     / * Compute-големия общ делител се използва алгоритъм на Евклид * /
     __asm__ __volatile__ ("movl% 1,% EAX;"
                           "Movl% 2% ebx;"
                           "CONTD: cmpl $ 0, ebx%;"
                           "Je направено;"
                           "Xorl% EDX,% EDX;"
                           "Idivl% ebx;"
                           "Movl ebx%%%% EAX;"
                           "Movl% EDX,% ebx;"
                           "JMP CONTD;"
                           "DONE: movl% EAX, 0%;": "= G" (резултат): "ж" (а), "ж" (б)
     );

     върне резултат;
 }

 INT главната () {
     Int първо, второ;
     printf ("Въведете две цели числа:");
     scanf ("% г% г", и първо, и второ);

     printf ("GCD% г &% г% D \ N", първо, второ, GCD (първо, второ));

     връщането на 0;
 }