Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Java программирование > Общие вопросы по Java, Java SE, Kotlin
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.11.2009, 12:05   #1
OCTAGRAM
Oldschool geek
Форумчанин
 
Аватар для OCTAGRAM
 
Регистрация: 09.03.2009
Сообщений: 611
По умолчанию Реализация java.util.concurrent.atomic.AtomicI nteger на x86

Меня интересует, в какой x86 код транслируются методы get() и set() сабжа. И метод lazySet() тоже, если такой есть. Скорее всего, lazySet() на x86 — это обычная запись в память.

В online исходниках GCJ я нашёл вот такое:

http://gcc.gnu.org/viewcvs/trunk/lib....h?view=markup

а где там реализация, непонятно.

Мне не очевидно, как при реализации расставлены барьеры памяти и вообще какими x86 инструкциями лучше реализовывать get() и set() (не в Java). Чтобы не рисковать, я пока реализую set() как lock xchgl, пусть даже мне не очень нужно прежнее значение, а get() — как lock xaddl, добавляя ноль. Думаю, всё это не очень оптимально, зато уж точно корректно.
If you want to get to the top, you have to start at the bottom

http://pascal.net.ru/
OCTAGRAM вне форума Ответить с цитированием
Старый 22.11.2009, 20:44   #2
alexinspir
Новичок
Джуниор
 
Аватар для alexinspir
 
Регистрация: 26.08.2008
Сообщений: 1,010
По умолчанию

В исходниках Java наврятли получится найти ответ. вам нужно копать в сторону ассемблера.
Однако:
Код:
package java.util.concurrent.atomic;
import sun.misc.Unsafe; //<<<<<<<<<<<<<<

public class AtomicInteger extends Number implements java.io.Serializable {
    private static final long serialVersionUID = 6214790243416807050L;

    // setup to use Unsafe.compareAndSwapInt for updates
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long valueOffset;

    static {
      try {
        valueOffset = unsafe.objectFieldOffset
            (AtomicInteger.class.getDeclaredField("value"));
      } catch (Exception ex) { throw new Error(ex); }
    }

    private volatile int value;

    public AtomicInteger(int initialValue) {
        value = initialValue;
    }

    public AtomicInteger() {
    }

    public final int get() {
        return value;
    }


    public final void set(int newValue) {
        value = newValue;
    }

    public final void lazySet(int newValue) {
        unsafe.putOrderedInt(this, valueOffset, newValue);
    }


    public final int getAndSet(int newValue) {
        for (;;) {
            int current = get();
            if (compareAndSet(current, newValue))
                return current;
        }
    }

    public final boolean compareAndSet(int expect, int update) {
	return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }


    public final boolean weakCompareAndSet(int expect, int update) {
	return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }


    public final int getAndIncrement() {
        for (;;) {
            int current = get();
            int next = current + 1;
            if (compareAndSet(current, next))
                return current;
        }
    }


    public final int getAndDecrement() {
        for (;;) {
            int current = get();
            int next = current - 1;
            if (compareAndSet(current, next))
                return current;
        }
    }


    public final int getAndAdd(int delta) {
        for (;;) {
            int current = get();
            int next = current + delta;
            if (compareAndSet(current, next))
                return current;
        }
    }


    public final int incrementAndGet() {
        for (;;) {
            int current = get();
            int next = current + 1;
            if (compareAndSet(current, next))
                return next;
        }
    }


    public final int decrementAndGet() {
        for (;;) {
            int current = get();
            int next = current - 1;
            if (compareAndSet(current, next))
                return next;
        }
    }


    public final int addAndGet(int delta) {
        for (;;) {
            int current = get();
            int next = current + delta;
            if (compareAndSet(current, next))
                return next;
        }
    }


    public String toString() {
        return Integer.toString(get());
    }


    public int intValue() {
	return get();
    }

    public long longValue() {
	return (long)get();
    }

    public float floatValue() {
	return (float)get();
    }

    public double doubleValue() {
	return (double)get();
    }

}
Если пойти по зависимостям, то можно найти нужную нативную библиотеку и дезассемблировать ее.
Код из Sun JDK 6.13
ромик0: Cколько получают здешние модераторы?
pu4koff: У модераторов сдельная оплата труда. Выдал предупреждение - плюс к премии. Выдал бан - лучший модератор месяца со всеми вытекающими.
alexinspir вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Разрядность ОСи x86/x64 Veiron Win Api 11 13.12.2010 17:26
Переписать программку с x86 под x64 PnG Фриланс 6 02.11.2009 11:24
assembler x86-64 DEADHUNT Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 21 01.06.2009 22:38
USB driver для x86 Family Vladislav Компьютерное железо 0 29.04.2008 08:08