Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Страница 1 из 2 1 2 ПоследняяПоследняя
Показано с 1 по 10 из 12

Тема: dc_SleepFix

  1. #1
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±

    dc_SleepFix

    ВНИМАНИЕ: данная функция всё ещё не работает нигде, кроме функции main.
    В ней только исправлена ошибка с неправильными значениями в указателе вершины стека (stack/heap collision), возникающая при очень частом использовании оператора sleep.

    Скорее всего, вам эта функция нигде не пригодится, но я на всякий случай задокументирую её здесь.
    Возможное использование: проведение тестов, в которых оператор sleep используется очень часто (в циклах, например). Мне хватило 2037 раз, чтобы вызвать ошибку времени выполнения обычным sleep - при использовании dc_SleepFix её нет.
    Один из тестов можно найти здесь: http://pro-pawn.ru/showthread.php?13189

    PHP код:
    dc_SleepFix(time)    // by Daniel_Cortez \\ pro-pawn.ru
    {    // WARNING: This function is still only usable in main().
        // It just fixes the stack/heap collision error in default sleep().
        
    static heap_ptrstack_ptr;
        
    #emit    lctrl        2
        #emit    stor.pri    heap_ptr
        #emit    lctrl        4
        #emit    stor.pri    stack_ptr
        
    sleep(time);
        
    #emit    load.pri    stack_ptr
        #emit    sctrl        4
        #emit    load.pri    heap_ptr
        #emit    sctrl        2
    }
    #if defined _ALS_sleep
        #undef sleep
    #else
        #define _ALS_sleep
    #endif
    #define sleep(%0) dc_SleepFix(%0) 

    Автор: Daniel_Cortez
    Специально для Pro-Pawn.ru
    Копирование данной статьи на других ресурсах без разрешения автора запрещено!
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  2. 2 пользователя(ей) сказали cпасибо:
    $continue$ (13.01.2016) L0ndl3m (13.01.2016)
  3. #2
    Аватар для ziggi
    Проверенный

    Статус
    Оффлайн
    Регистрация
    14.05.2015
    Сообщений
    1,181
    Репутация:
    790 ±
    Вариант из fixes от Y_Less:
    PHP код:
    /* 
     * FIXES_sleep(const time)
     * 
     * FIXES:
     *     sleep
     */

    // Uses a little trick to consume part of the line and thus not match
    // our hooked version.
    #if defined _ALS_sleep
        #error _ALS_sleep defined
    #endif
    #define BAD_sleep%0\n%9 sleep%0

    #if FIX_sleep
        
    stock FIXES_sleep(ms)
        {
            
    // Call a native function that does very little, but saves the current
            // heap pointer.  Then return to save the accurate stack pointer.
            
    return heapspace(), ms;
        }
        
        
    #define _ALS_sleep
        
        #define sleep%0\n%9 sleep FIXES_sleep(%0)
        // This fixes another BIZZARE bug.  Just doing:
        //
        //  #define FIXES_sleep(%0;) FIXES_sleep(%0)
        //
        // Results in:
        //
        //  FIXES_sleep(n));
        //
        // Which clearly it shouldn't.  I've stepped through the compilation and that
        // extra bracket comes from nowhere!
        #define FIXES_sleep(%0;) FIXES_sleep _FIXES_SLEEP_BRACKET %0);
        #define _FIXES_SLEEP_BRACKET (
    #endif 

  4. #3
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от ziggi Посмотреть сообщение
    Вариант из fixes от Y_Less:
    PHP код:
    /* 
     * FIXES_sleep(const time)
     * 
     * FIXES:
     *     sleep
     */

    // Uses a little trick to consume part of the line and thus not match
    // our hooked version.
    #if defined _ALS_sleep
        #error _ALS_sleep defined
    #endif
    #define BAD_sleep%0\n%9 sleep%0

    #if FIX_sleep
        
    stock FIXES_sleep(ms)
        {
            
    // Call a native function that does very little, but saves the current
            // heap pointer.  Then return to save the accurate stack pointer.
            
    return heapspace(), ms;
        }
        
        
    #define _ALS_sleep
        
        #define sleep%0\n%9 sleep FIXES_sleep(%0)
        // This fixes another BIZZARE bug.  Just doing:
        //
        //  #define FIXES_sleep(%0;) FIXES_sleep(%0)
        //
        // Results in:
        //
        //  FIXES_sleep(n));
        //
        // Which clearly it shouldn't.  I've stepped through the compilation and that
        // extra bracket comes from nowhere!
        #define FIXES_sleep(%0;) FIXES_sleep _FIXES_SLEEP_BRACKET %0);
        #define _FIXES_SLEEP_BRACKET (
    #endif 
    Да, я видел этот вариант, но он меня не устроил.

    В комментарии можно увидеть, что автор фикса (Y_Less) утверждает, якобы нативная функция (heapspace) сохраняет текущий указатель кучи ("Call a native function that does very little, but saves the current heap pointer.").
    Интересно, где он это увидел? Код функции можно посмотреть здесь. Всё, что делает функция - возвращает разницу между значениями в указателях стека и кучи, т.е. свободное пространство в секции стека/кучи. Никакого сохранения указателей стека, кучи или фрейма стека в ней нет.
    По сути оператор sleep заменяется на какую-то функцию, которая даже не производит никакой приостановки выполнения кода. С таким же успехом можно заменить sleep на функцию-пустышку.
    PHP код:
    stock FIX_Sleep(ms) return ms
    В чём смысл такого "фикса"? Можно ли это вообще назвать "фиксом"? Удивительно, почему этого до сих пор никто не заметил - вроде бы среди заморской аудитории много кто пользуется этим инклудом.
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  5. #4
    Аватар для ziggi
    Проверенный

    Статус
    Оффлайн
    Регистрация
    14.05.2015
    Сообщений
    1,181
    Репутация:
    790 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Да, я видел этот вариант, но он меня не устроил.

    В комментарии можно увидеть, что автор фикса (Y_Less) утверждает, якобы нативная функция (heapspace) сохраняет текущий указатель кучи ("Call a native function that does very little, but saves the current heap pointer.").
    Интересно, где он это увидел? Код функции можно посмотреть здесь. Всё, что делает функция - возвращает разницу между значениями в указателях стека и кучи, т.е. свободное пространство в секции стека/кучи. Никакого сохранения указателей стека, кучи или фрейма стека в ней нет.
    По сути оператор sleep заменяется на какую-то функцию, которая даже не производит никакой приостановки выполнения кода. С таким же успехом можно заменить sleep на функцию-пустышку.
    PHP код:
    stock FIX_Sleep(ms) return ms
    В чём смысл такого "фикса"? Можно ли это вообще назвать "фиксом"? Удивительно, почему этого до сих пор никто не заметил - вроде бы среди заморской аудитории много кто пользуется этим инклудом.
    Хм, и правда, спасибо. В ближайшее время обновлю свой форк этой либы.

  6. #5
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от ziggi Посмотреть сообщение
    Хм, и правда, спасибо. В ближайшее время обновлю свой форк этой либы.
    ИМХО, вряд ли в SA:MP есть хоть что-то, вызывающее задержку без вызова коллбэка (т.е. в пределах вызывающей функции) и без создания нагрузки на процессор. В конце концов, он для того и создан, чтобы быть однопоточным. Но если всё же будут идеи, постараюсь сделать PR в твоём форке.
    Последний раз редактировалось Daniel_Cortez; 13.01.2016 в 19:44. Причина: --
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  7. #6
    Аватар для ziggi
    Проверенный

    Статус
    Оффлайн
    Регистрация
    14.05.2015
    Сообщений
    1,181
    Репутация:
    790 ±
    Стоп. Я протестировал стандартную функцию, хватило примерно 1300 вызовов для получения этой ошибки. Затем я взял фикс от Y_Less и он, походу, действительно работает, ибо на 27 тысячах итераций полёт нормальный.

    Тестировал очень просто:
    PHP код:
    main()
    {
        new 
    a;
        while (++
    a) {
            
    printf("%d"a);
            
    sleep(0);
        }


  8. #7
    Аватар для Daniel_Cortez
    "Это не хак, это фича"

    Статус
    Оффлайн
    Регистрация
    06.04.2013
    Адрес
    Novokuznetsk, Russia
    Сообщений
    2,192
    Репутация:
    2589 ±
    Цитата Сообщение от ziggi Посмотреть сообщение
    Стоп. Я протестировал стандартную функцию, хватило примерно 1300 вызовов для получения этой ошибки. Затем я взял фикс от Y_Less и он, походу, действительно работает, ибо на 27 тысячах итераций полёт нормальный.

    Тестировал очень просто:
    PHP код:
    main()
    {
        new 
    a;
        while (++
    a) {
            
    printf("%d"a);
            
    sleep(0);
        }

    Действительно, стоп. А теперь назад.
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    По сути оператор sleep заменяется на какую-то функцию, которая даже не производит никакой приостановки выполнения кода. С таким же успехом можно заменить sleep на функцию-пустышку.
    Врема простоя и нагрузку на процессор проверял?
    Индивидуально в ЛС по скриптингу не помогаю. Задавайте все свои вопросы здесь (click).

  9. #8
    Аватар для ziggi
    Проверенный

    Статус
    Оффлайн
    Регистрация
    14.05.2015
    Сообщений
    1,181
    Репутация:
    790 ±
    Цитата Сообщение от Daniel_Cortez Посмотреть сообщение
    Действительно, стоп. А теперь назад.

    Врема простоя и нагрузку на процессор проверял?
    Да, оно работает. Здесь же не подмена функции, а её "дополнение":
    PHP код:
    #define sleep%0\n%9 sleep FIXES_sleep(%0) 
    Вот во что превращается код после работы препроцессора:
    PHP код:
    main()
    {
        new 
    a;
        while (++
    a) {
            
    printf("%d"a);
            
    sleep FIXES_sleep ( (100));    }

    Последний раз редактировалось ziggi; 13.01.2016 в 20:08.

  10. #9
    Аватар для $continue$
    Пользователь

    Статус
    Оффлайн
    Регистрация
    02.08.2014
    Адрес
    г. Киров (aka Вятка)
    Сообщений
    1,487
    Репутация:
    276 ±
    Один вопрос:
    PHP код:
        stock FIXES_sleep(ms)
        {
            
    // Call a native function that does very little, but saves the current
            // heap pointer.  Then return to save the accurate stack pointer.
            
    return heapspace(), ms;
        } 
    На какой сначала возвращаеться: heapspace а потом ms?
    Если в итоге вернет ms?
    Value your freedom or you will lose it, teaches history. "Don't bother us with politics," respond those who don't want to learn. (c) Richard Stallman

  11. #10
    Аватар для ziggi
    Проверенный

    Статус
    Оффлайн
    Регистрация
    14.05.2015
    Сообщений
    1,181
    Репутация:
    790 ±
    Цитата Сообщение от $continue$ Посмотреть сообщение
    Один вопрос:
    PHP код:
        stock FIXES_sleep(ms)
        {
            
    // Call a native function that does very little, but saves the current
            // heap pointer.  Then return to save the accurate stack pointer.
            
    return heapspace(), ms;
        } 
    На какой сначала возвращаеться: heapspace а потом ms?
    Если в итоге вернет ms?
    heapspace не возвращается, а просто выполняется. Код написан "под" return для того, чтобы сократить размер AMX (по словам Y_Less).

 

 
Страница 1 из 2 1 2 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •