Красавчик, ivagor лучший!
Красавчик, ivagor лучший!
С любовью к вам, Yandex.Direct
Размещение рекламы на форуме способствует его дальнейшему развитию
недавно столкнулся с необходимостью лока, это когда процедура запрещает повторный вызов самой себя или работу с областью памяти. например в прерывании.
я не знаю как данная задача решается на современном железе но на z80 не придумал ничего лучше inc (rp)
можно заменить на djnz по обстоятельствамКод:inc (ix+stHead.lock) ld b, (ix+stHead.lock) dec b jr z, .cont .exit dec (ix+stHead.lock) ret .cont
хотел понять есть ли варианты лока?
А вдруг будет целый шторм запусков, и inc-ов будет выполнено постоянно больше dec-ов?
Может изначально в ячейке ложить единицу, и перед декрементом её проверять?
Теперь вроде, даже в сильный шторм, проскакивать выполнение должно.Код:ld b, (ix+stHead.lock) dec b ret nz dec (ix+stHead.lock) jr z, .cont .exit inc (ix+stHead.lock) ret .
а теперь посмотри что будет если прерывание придет между 1 и 2 командой. в моем случае сколько бы не было инков на континуе перейдет только первый
- - - Добавлено - - -
хотя тупанул, плохого ничего не случится, но и первая проверка будет бесполезной, как защита от гипотетического шторма nmi тоже не спасет но вообще имеет смысл. даже скорее для локов когда лочится в одной процедуре а снимается лок в другой, подход с предварительной проверкой обязателен. спасибо полезно.
- - - Добавлено - - -
хотя еще прикинул, а потом еще, ну для устройств далеких от спектрума и со специфическим софтом наверное и надо доп проверку, у нас не подобрал условий для переполнения 255, даже больше 3 не могу придумать.
Последний раз редактировалось krt17; 08.09.2025 в 09:27.
Reobne(08.09.2025)
Это все не рабочее, просто проверяй предположением что допустим прерывание пришло после первой комманды. Эти локи с комбинациями с di такое себе.
а вот это я точно использую, уменьшает начальную проверку. и b грузить не надо
- - - Добавлено - - -
на самом деле все варианты норм, потому что у нас проц не может одновременно выполнять несколько потоков и к локу требования намного меньше, выполнение кода все равно будет завершено полностью перед другой обработкой потому как выполнение после проверки флага и изменения флага, необходимости одновременной проверки и изменения нет.
спасибо всем, пересмотрю вообще требования.
Reobne(08.09.2025)
Для однократного вызова процедуры можно глушить ретурном.
Код:proc_ push af ld a,#C9 ; 'ret' ld (proc_),a pop af ; 7 байтов с push , 5 без них ...или можно встроить семафор в тело программыКод:proc_ ld hl,proc_ ; или если например hl не жалко ld (hl),#C9 ...
- - - Добавлено - - -Код:proc_ ld a,1 or a ret z ; jr z, exit xor a ld (proc_+1),a ...
Ещё пришло на ум . Если однократных вызовов надо много, то можно сделать процедуру залочивания.
Код:; процедура лока locker_ ex (sp),hl ; после первого применения поставит заглушку 'ret' push hl ; по вызывавшему адресу dec hl dec hl dec hl ld (hl),#C9 pop hl ex (sp),hl ret ; применение proc_ call locker_ ; 3 байта на вызов ...
тут даже речь не совсем про процедуру, с одними данными могут работать много процедур и лочить их должна одна пока не отпустит. анлок может вообще вызываться не из нее.
еще немного прикинул, требования к локу становятся изначальными если кто то решит сделать систему с многозадачностью, в этом случае строгий лок необходим и вариант с inc (rp) наверное единственный.
у меня потребность возникла при работе со списками, не хотелось бы чтобы прерывание что то удаляло в списке когда основной код берет из него данные. хотя опять же повторюсь, надо просмотреть все варианты, возможно мне это не нужно будет
А если в начале процедуры модифицировать первый байт как ret, и в конце - возвращать в nop?
Тогда всегда сможет работать только одна.
Heavy on the disasm
Eric and the disasm
Mask 3: Venom strikes disasm
Bard's disasm
в общем случае лок отдельной процедуры это пол задачи, чаще нужно лочить данные. В этом случае все становится сложнее, выделение области для переменных на стеке или вообще без переменных в памяти. грубо говоря есть процедура удаления элемента списка и добавления, если удалять в основном цикле а добавлять в прерывании (дизайн не очень согласен, но списки разные бывают, допустим список с нажатыми клавишами) возможны нарушения данных. как то так. Возможно пересмотрю подход, я просто вернулся к https://vtrd.in/release.php?r=f60879...2e1f79f01055fc и мне понадобились некоторые базовые вещи, по классике не охота, а по другому пока не умею.
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)