Запуск тяжелых приожений

Internal structure and you change requests/suggestions
  • В dll.inc есть процедура load_file, в ней присутствует следующее гениальное решение:

    Code: Select all

            pushfd
            cli
            stdcall unpack, [file], eax
            popfd
    
    Плевать на прерывания, многозадачность и прочие мелкие радости жизни! РаспакоФка наше фсе! Чем собственно и занимается трудолюбивый CPU. :mrgreen:

    Если убрать cli то блокировка исчезает. Однако у меня нет уверенности, что это не вызовет каких либо дополнительных конфликтов.
  • Итак счастье случилось в r. 1275 или сразу после выпуска K0750.
    Остается гадать - это случайно забытая временная затычка для отладки или постоянное решение для загрузки видеодрайвера ATI. У меня нет видеокарт ATI, чтобы проверить и вынести точный вердикт.
  • SVN r. 2486 - исправление для ревизии 1275.

    Заменил CLI на мьютекс:
    Spoiler:

    Code: Select all

            push    eax
    .wait_lock:
            cmp     [unpack_mutex], 0
            je      .get_lock
            call    change_task
            jmp     .wait_lock
    
    .get_lock:
            mov     eax, 1
            xchg    eax, [unpack_mutex]
            test    eax, eax
            jnz     .wait_lock
            pop     eax
    
            stdcall unpack, [file], eax
    
            mov     [unpack_mutex], 0
    Да, и эти люди запрещают мне ковыряться в носу лишний раз вызывать перерисовку курсора. "Лучше день потерять, а потом за 5 минут долететь!" говорят они. :wink:

    З.Ы. Зашибись! Пообщался с умным человеком - с самим собой. :?
  • Есть как раз ATI. Дай этот fplay -проверю.
  • Уже не нужно. Я не стал убирать блокировку. поскольку процедура распаковки не реентерабельна (используются глобальные переменные вместо локальных). Просто заменил "тяжелый" вариант CLI на более "легкий" вариант с мьютексом. Теперь блокируется только вызов процедуры распаковки (кто первым встал - того и тапки), а прерывания и остальные вещи происходят нормально.
  • Mario
    У ядра есть свои блокирующие мьютексы: mutex_init() mutex_lock() mutex_unlock()
  • Вообще то, по хорошему, такие фундаментальнsе вещи должны иметь документацию, хотя бы краткую. Пока такой документации нету - я не буду переделывать свой код. Если есть желание сделать лучше чем сделано - я не возражаю.

    З.Ы. Да, и как я уже сказал в чате - я не сам выдумал код мьютекса, а взял готовое решение из taskman.inc и значит раз оно там присутствует, то оно вполне жизнеспособно.
  • Я давал описание в одной из тем, а насчёт общей документации согласен.
  • Ну, раз ты сам не помнишь - где ты давал описание, то я тем более его не смогу выделить из обсуждаемых вопросов, где вы с Артемом просто болтали.
  • Все описания функций ядра я даю в одной теме, разумеется её никто не читает и поиском не пользуется.
  • Я не работал с линуксовыми мьютексами и понимаю отнюдь не всю специфику обсуждаемую.
    Еще я плохо знаю Сишный синтаксис и не знаю как запись вида:

    Code: Select all

    void __attribute__ ((fastcall)) mutex_lock(struct mutex*);
    должна выглядеть для ассемблера.
  • Например так

    Code: Select all

            mov     ecx, heap_mutex
            call    mutex_lock
    В ядре много примеров.
  • Хорошо, попробую.
  • И вот это вот портянка:
    Spoiler:

    Code: Select all

    align 4
    mutex_lock:
    
            dec     [ecx+MUTEX.count]
            jns     .done
    
            pushfd
            cli
    
            sub     esp, sizeof.MUTEX_WAITER
    
            list_add_tail esp, ecx      ;esp= new waiter, ecx= list head
    
            mov     edx, [TASK_BASE]
            mov     [esp+MUTEX_WAITER.task], edx
    
    .forever:
    
            mov     eax, -1
            xchg    eax, [ecx+MUTEX.count]
            dec     eax
            jz      @F
    
            mov     [edx+TASKDATA.state], 1
            call    change_task
            jmp     .forever
    @@:
            mov     edx, [esp+MUTEX_WAITER.list.next]
            mov     eax, [esp+MUTEX_WAITER.list.prev]
    
            mov     [eax+MUTEX_WAITER.list.next], edx
            mov     [edx+MUTEX_WAITER.list.prev], eax
            cmp     [ecx+MUTEX.lhead.next], ecx
            jne     @F
    
            mov     [ecx+MUTEX.count], 0
    @@:
            add     esp, sizeof.MUTEX_WAITER
    
            popfd
    .done:
            ret
    стоит того чтобы заменить:
    Spoiler:

    Code: Select all

            push    eax
    .wait_lock:
            cmp     [unpack_mutex], 0
            je      .get_lock
            call    change_task
            jmp     .wait_lock
    
    .get_lock:
            mov     eax, 1
            xchg    eax, [unpack_mutex]
            test    eax, eax
            jnz     .wait_lock
            pop     eax
    
    В обоих случаях есть столь "ненавистный":

    Code: Select all

            call    change_task
    Да еще и CLI задействуется. :(

    Я конечно переделаю, но люди иногда хотят странного - моя не понимат!
  • Who is online

    Users browsing this forum: No registered users and 5 guests