Отсутствуют ожидаемые команды из .Net System.Threading.Interlocked - PullRequest
2 голосов
/ 09 апреля 2011

Класс .Net System.Threading.Interlocked в первую очередь предназначен для предоставления функций префикса ASM LOCK.

Однако я ломаю голову над вопросом, почему Microsoft ограничивает количество поддерживаемых команд.Я думал, что это проблема "C #", но быстрый взгляд на MSDN исправил эту идею.Это ограничение .Net.

Например, нет Interlocked.Or, но в ASM можно сказать «LOCK OR eax, ebx».Так почему бы не заблокировать. Или (ссылка x, 10).

Это не имеет смысла для меня.Почему нет эквивалента LOCK OR, но у них есть LOCK ADD.Первый невероятно полезен.

Так что я проверил GCC и, конечно же, все там.Каждая совместимая команда LOCK: атомарные команды GCC

Может кто-нибудь пролить свет на то, почему MS пропустила большинство команд, включенных в L86 x86?

Ответы [ 2 ]

3 голосов
/ 09 апреля 2011

Класс .Net System.Threading.Interlocked в первую очередь предназначен для предоставления функций префикса ASM LOCK.

Нет, в первую очередь он предназначен для предоставления элементарных операций над переменными, включая барьеры памяти.

Из документации:

Методы этого класса помогают защитить от ошибок, которые могут возникнуть, когда планировщик переключает контексты, когда поток обновляет переменную, к которой могут обращаться другие потоки, или когда два потока одновременно выполняются на отдельных процессорах. Члены этого класса не генерируют исключения.

Теперь так получается, что инструкция LOCK также предлагает эти возможности, но нет явной попытки имитировать всю функциональность инструкции LOCK. Если бы это было намерением, не думаете ли вы, что инструкция была бы упомянута?

Я подозреваю , что разработчики API решили, что они предложат наиболее часто требуемые атомарные операции - вместо того, чтобы взглянуть на инструкцию LOCK и решить, что пропустить.

Подобно языковым функциям, функции API связаны с определенными затратами, и каждая из них должна заработать свое место. Interlocked - довольно редко используемый класс в любом случае - я подозреваю, что число разработчиков, требующих Interlocked.Or, будет действительно очень маленьким.

Также помните, что .NET работает не только на x86. Я понятия не имею, имеют ли инструкции в процессорах Windows Phone 7 (которые я предполагаю ARM) те же возможности, что и инструкция LOCK x86, например.

0 голосов
/ 30 июля 2012
/// <summary>
/// .NET: atomically set a bit in a 32-bit integer in shared memory
/// </summary>
/// <param name="status">memory location at which to atomically set a single bit</param>
/// <param name="singleton_bit">should have only one bit set (i.e. a power of two);
/// otherwise it is not possible to tell which caller enacted the change.</param>
/// <returns>
/// Returns the previous value at <paramref name="pi"/>. If the indicated bit is cleared 
/// in this return value then this caller enacted the change. If the indicated bit is set 
/// in the return value then no action was taken.
public static int InterlockedSetBit(ref int pi, int singleton_bit)
{
    Debug.Assert((singleton_bit & (singleton_bit - 1)) == 0);
    int _cur = pi;
    do
        if ((_cur & singleton_bit) != 0)
            return _cur;
    while (_cur != (_cur = Interlocked.CompareExchange(ref pi, _cur ^ singleton_bit, _cur)));
    return _cur;
}

/// <summary>
/// .NET: atomically clear a bit in a 32-bit integer in shared memory
/// </summary>
/// <param name="status">memory location at which to atomically clear a single bit</param>
/// <param name="singleton_bit">should have only one bit set (i.e. a power of two);
/// otherwise it is not possible to tell which caller the change.</param>
/// <returns>
/// Returns the previous value at <paramref name="pi"/>. If the indicated bit is set 
/// in this return value then this caller enacted the change. If the indicated bit is clear 
/// in the return value then no action was taken.
public static int InterlockedClearBit(ref int pi, int singleton_bit)
{
    Debug.Assert((singleton_bit & (singleton_bit - 1)) == 0);
    int _cur = pi;
    do
        if ((_cur & singleton_bit) == 0)
            return _cur;
    while (_cur != (_cur = Interlocked.CompareExchange(ref pi, _cur ^ singleton_bit, _cur)));
    return _cur;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...