1. C++ / Говнокод #12542

    +16

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    BOOL EnsureThreadIsSuspended (HANDLE hThread, Thread* pThread)
    {
        STATIC_CONTRACT_NOTHROW;
        STATIC_CONTRACT_GC_NOTRIGGER;
    
        WRAPPER_CONTRACT;
    
        CONTEXT ctx;
        ctx.ContextFlags = CONTEXT_INTEGER;
        BOOL ret;
        ret = ::GetThreadContext(hThread, &ctx);
    
        return ret;
    }

    А ведь и правда, никто не гарантирует, что поток будет остановлен к тому моменту, когда SuspendThread() вернет управление...

    Запостил: Ccik, 06 Февраля 2013

    Комментарии (23) RSS

    • Зачем так?
      Ответить
      • Я не знаю, почему именно так. А как еще?
        Ответить
    • И в c++ контракты затащили... мало там своего говна.
      Ответить
      • > GC
        и сборщик мусора
        это точно с++?
        Ответить
        • исходники .net
          Ответить
        • все ссылки ведут на ms COM+
          Ответить
        • > ::GetThreadContext
          Такие пространства имён я больше нигде не видел.
          Может, это какой-нибудь Managed C++?
          И мы не можем знать точно, что означает GC
          Ответить
          • а что такого в явном указании глобального пространства имён?
            я сам сторонник винапишные и прочие сишкоблядские высеры в крестосвятом коде так украшать
            Ответить
            • Я тоже так делаю. Просто наличие :: даёт возможность судить, что это всё-таки c++ (или perl или ruby, но они по остальному синтаксису не подходят). Это ответ на
              > это точно с++?
              Ответить
    • "[...] SuspendThread() [...]"

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

      100% случаев использования SuspendThread() на виндах которые я видел были 100% ГК.
      Ответить
      • Ну, я эмулировал аппаратные прерывания через SuspendThread() (подменял EIP через SetThreadContext()). Не знаю, как бы я это делал без SuspendThread(). Алсо, как останавливать поток для той же сборки мусора, например? Другое дело, что делать SuspendThread() для синхронизации это пиздец, да.
        Ответить
        • "Ну, я эмулировал аппаратные прерывания через SuspendThread() (подменял EIP через SetThreadContext()). Не знаю, как бы я это делал без SuspendThread()."

          ... в смысле "эмулировал аппаратные прерывания"? зачем user space софту нужны прерывания?? вся прелесть user space'а как раз и заключается в том что прерывания как бы и не существуют.

          "Алсо, как останавливать поток для той же сборки мусора, например?"

          так а зачем поток то суспендить? ява успешно это делает без суспендов. new просто подвисает на локе, ожидая когда GC кончит пулы чистить. и это только в том случае если new не смог найти куска свободной памяти.
          Ответить
          • > ... в смысле "эмулировал аппаратные прерывания"? зачем user space софту нужны прерывания?? вся прелесть user space'а как раз и заключается в том что прерывания как бы и не существуют.

            Отлаживал операционочку в userspace.

            > так а зачем поток то суспендить? ява успешно это делает без суспендов. new просто подвисает на локе, ожидая когда GC кончит пулы чистить. и это только в том случае если new не смог найти куска свободной памяти.

            В .net они както там в фоновом режиме собирают. Я не вникал.
            Ответить
            • > > зачем user space софту нужны прерывания??

              > Отлаживал операционочку в userspace.

              ндя... извращенец. :)

              JTAG не дешевле ли было купить? или как линух - запускать ядно под отладчиком, удаленно контролируемым через серийный порт? (удаленный протокол gdb я слышал тривиален.) или под *нихом сигналами эмулировать: там setjmp/друзья почти официально поддерживается.

              по моему опыту такие извращения себя редко оправдывают. если код чистая логика, то его часто можно и в программу сконвертировать (что я делал для сетевых протоколов). а если код драйвера, то там извраты просто не помогают: заморочки железа софтом не эмулируются.
              Ответить
              • По сути, я и написал реализацию механизма, аналогичного unix-сигналам, да. Вообще, в винде APC, но на них накладываются ограничения при работе с ними из userspace (выполняются только если поток-адресат заблокирован, подробнее на msdn, если интересно).

                Просто была студенческая поделка просто вместо нудных лаб. Эмуляцию достаточно достоверную удалось сделать и даже сдать это дело не запускаяя на железе. Понятно, что тонкостей работы реально аппаратуры тут не сэмулируешь, а вытеснение потока по таймеру - вполне. С JTAGами и виртуалками возиться не хотелось.
                Ответить
      • А как же SIGSTOP/SIGCONT?
        Ответить
      • В .NET'е (чего это является исходником) нужно уметь кооперативно саспендить треды в так называемых safe-point'ах, чтобы производить сборку мусору и много разного такого сервисного функционала по мелочи. Подвисать new на локе как в Java как-то стремновато, попахивает потенциальным дэдлоком... У .NET'а система reliability посложнее, чем у Java. Там есть всякие constrained regions и прочая мутотень, сложная в реализации .NET потоки основаны на fiber'ах и могут мигрировать с физического потока на поток. Лочить как-то небезопасно. Авторы явно писали этот код сообща с авторами ядра Windows, так что они наверное лучше знают, что производительнее и надёжнее, чем мы.
        Ответить
    • Не вижу использования параметра pThread
      Ответить
    • судя по коду, это исходник ROTOR
      Ответить

    Добавить комментарий