А я утверждаю, что эта конструкция, если она используется именно так, как написано, не корректна ни на какой машине, ни на старой ни на новой. Задача 1 выполняет BC и прерывается после этой команды. Задача 2 не перейдет на LABELX, так как модификация еще не произошла, выполниться OI и т.д. После возобновления первой задачи она пойдет по той же ветке в соотвествии с ранее сформированным признаком результата BC. Согласны ? Корректная реализация, например, такая: ENQ BC 0,LABELX OI X'F0',*-4 DEQ
Quote
настоящие программисты используют самомодифицирующийся код
если говорить серъезно, то модификация кода это ненужные излишества, а вот без модификации статических данных обойтись иногда не представляется возможным, например, для "глобальной" инициализации
Сообщение отредактировал Gregory - Чт, 13.08.2009, 10:26
, и утверждаю, что на моих машинах это было реентерабельно! Т.е. второй и последующий входы шли по другой ветке, но конструкция ДОПУСКАЛА повторый вход, что и есть по определению re-enterable . Ну, кто бросит в меня камень ?
А вот тут и я свои три копейки вброшу. У меня тоже такая конструкция работала, но под CMS)). Там заведомо и маска правильная, и полномочия. Но CMS - не OS, курица - не птица.
Вот очень кстати, к вопросу о реентерабельности ... Ща пишу подпрограмку на Це, которая должна быть реентерабельна ... а будет она вызываться из PLя, да под CICSом (мы не ищем легких путей!) При первом вызове она должна хватануть и разметить кусочек памяти, к которому при последующих вызовах будет обращаться. Возникает 2 вопроса: 1. А как бы мне запомнить адрес этой самой области ?... Вариант - сделать параметром, т.о. свалить эту проблему на голову вызывающего не очень хорош, ибо дальнейшие варианты а) он проблему решит, но значение параметра "глючность" от этого резко вырастет; б) он протрахается некоторе время, после чего обратится за помощью ко мне, и что я ему скажу ?! 2. А что кошерней использовать (из под С) в качестве ENQ/DEQ ?
Добавлено (29.08.2009, 19:54) --------------------------------------------- И опять о реентерабельности.... Господа, прокомментируйте пожалуйста следующий факт. Делаю тест. job, где в начале компилируется в библиотеку функция на С, затем компилируется, собирается с этой функцией и выполняется голова на PL. Там где C - у меня вверху (вне тела функции) объявлены переменные для сохранения некоторых параметров между вызовами. Кстати, меня прикололо, что транслятор каждую из этих переменных сделал CSECT. Но не об этом речь. Короче, отлаживаю, наконец тест начинает делать то что я хочу. По приколу пишу PARM.LKED='RENT', запускаю, и с обреченным лицом жду 0C4. У-у-у-пс... ожидаемого 0C4 не приходит. Смотрю в листинг - проверяю себя, вижу несколько предупреждений: IEW2609W 5104 SECTION SECAPISA USABILITY ATTRIBUTE OF NON-REUSABLE CONFLICTS WITH REQUESTED USABILITY OF REENTRANT. и ниже - SAVE MODULE ATTRIBUTES: .... RENT YES - т.е., я не глючу. Я запустил [формально] реентерабельную программу, пишущую в свое тело, и мне позволили это сделать. Спрашивается - почему ?
При первом вызове она должна хватануть и разметить кусочек памяти, к которому при последующих вызовах будет обращаться.
При первом вызове из данной задачи? Или из любой задачи? То есть у Вас область локальная для каждой задачи или глобальная для всех? В первом случае можно использовать user field в текущем TCB (данной задачи). Во втором случае можно использовать user field предыдущего TCB (родительской задачи). В обоих случаях можно использовать обсуждавшуюся выше технику с ENQ/DEQ. Но при работе в CICS я думаю, правильно использовать для этого TDQ.
Quote
Я запустил [формально] реентерабельную программу, пишущую в свое тело, и мне позволили это сделать
Почитайте эту дискуссию с начала... Я писал, что атрибут реентерабельности устанавливается для загрузочного модуля без каких-либо проверок, потому что проверить, является ли программа реентерабельной невозможно. И почему это при вызове программа должна аварийно завершиться при самомодификации? Если программа вызывается из задания (PGM=) или из его TSO эквивалента (CALL), то вообще не имеет НИКАКОГО значения, реентерабельная программа или повторно входимая (REUS). Чтобы увидеть разницу, программа должна вызываться из подзадач (т.е. ATTACH), причем из нескольких (>1). И если одна и та же программа вызывается в разных заданиях как PGM=, ее реентерабельность опять же не имеет НИКАКОГО значения, потому что у каждого задания свое собственное адресное пространство. Разные задания будут использовать один и тот же код, если вызываемая программа найдена в PLPA. Или Вы проверяли программу под CICS? Как именно вызывается программа из CICS? По поводу ENQ/DEQ в C... Если Ваш код работает под CICS, то самое правильное - использовать вызовы (функции) CICS для подобных целей. Насколько я знаю (к сожалению, очень поверхностно), там это есть - CICS ENQ/CICS DEQ...
Сообщение отредактировал Gregory - Сб, 29.08.2009, 22:16
При первом вызове из данной задачи? Или из любой задачи? То есть у Вас область локальная для каждой задачи или глобальная для всех?
Из любой. Область одна для всех.
Quote
В первом случае можно использовать user field в текущем TCB (данной задачи).
Дык кто ж меня пустит туда писать ? Програмка самая что ни на есть проблемная, и у меня даже нет прямого контакта с работающими там людьми. Это у себя на машине я мог бы делать все что захочу, а там я не у себя - простите, защита памяти. (А даже если б мог - не факт, что уже не занято кем-то...)
Quote
Но при работе в CICS я думаю, правильно использовать для этого TDQ.
Не знаю, к сожалению, что это такое.
Quote (Gregory)
Почитайте эту дискуссию с начала... Я писал, что атрибут реентерабельности устанавливается для загрузочного модуля без каких-либо проверок, потому что проверить, является ли программа реентерабельной невозможно.
А я, типа, в курсе
Quote
И почему это при вызове программа должна аварийно завершиться при самомодификации?
Потому что. Не знаю как в z/OS управление памятью организовано, но хорошо помню что под MVT реентерабельный модуль мог быть загружен под 0-й ключ. И ежели программа юзерская - получите 0С4 и распишитесь. (Кстати, XOpen об чем-то подобном упоминал - Вы прочтите начало дискуссии ) Но вот чего я а упор не помню - всегда ли она грузилась под 0-й ключ, или "в определенных случаях"...
Quote (Gregory)
Если Ваш код работает под CICS, то самое правильное - использовать вызовы (функции) CICS для подобных целей.
CICSа не знаю абсолютно. Просто ваще, полный ноль. (Вопрос "а хрена ли набрался наглости под него писать?" отвергается как неконструктивный)
CICS я не знаю , но точно могу посоветовать его почитать, раз уж писать под него придется. В Си прямой способ синхронизации - это семафоры, которые Юникс, которого в Киксе нельзя. Значит надо искать там...
зы: в виде бонуса, можно потом пальцы гнуть, в качестве ведущего спеца по киксу здесь.
зы2: вообще не представляю, как можно написать программу, не имея среды. Я бы не смог.
CICS я не знаю cry , но точно могу посоветовать его почитать, раз уж писать под него придется. cool
Фиговость в том, что следующий раз мне что-то подобное придется делать может через полгода - как раз успею забыть все что прочитал А на чтение доков времени не выделяют - начальство считает, что ежели я с мэйнфреймами знаком, то я просто сажусь и пишу.
Quote
В Си прямой способ синхронизации - это семафоры, которые Юникс, которого в Киксе нельзя. Значит надо искать там...
По моему было бы логично, если бы "семафорные" функции в каждой среде реализовывались адеквадным для нее образом. Есть ли основания предполагать, что IBM поступила не так ?...
Quote
зы: в виде бонуса, можно потом пальцы гнуть, в качестве ведущего спеца по киксу здесь. smile
Гнуть пальцы в нашей среде - занятие абсолютно бесперспективное. Меняется политика Партии, и через 2 месяца перед тобой гнет пальцы пионер, освоивший программирование на Бейсике на ПК "Агат" - ибо ты хоть с Бейсиком и справишься, но в специфике ввода-вывода на данном изделии ни ухо ни рыло, а пионер ее выучил наизусть, а на твои познания в области дисковых подсистем ему глубоко плевать. Я этот пример не придумал - до сих пор помню лица 2х системщиков, задыхающихся от возмущения, и глядящего свысока пионера
Quote
зы2: вообще не представляю, как можно написать программу, не имея среды. Я бы не смог. wacko
Ну, если эта тема нормально разовьется, может быть продавлю доступ на ту машину.
PUT SKIP EDIT('*** ========= BEFORE CALL ========= ***')(A); CALL FP->FUN ; PUT SKIP EDIT('*** ========= AFTER CALL ========= ***')(A); PUT SKIP;
END TESTFP;
SUB1: PROC ; PUT SKIP EDIT('*** --------THIS IS SUB1 --------- ***')(A); END SUB1 ;
Идея понятна: проверить могу ли я вызывать функцию через указатель на нее. Так вот, судя по ассемблерному коду, оператор CALL FP->FUN отрабатывает правильно. А вот закомментаренный оператор - транслятор жрать не хочет, говорит IBM1603I S 5.1 ADDR argument must not have the CONSTANT attribute. Не понимаю почему он так возмутился, но хрен с ним... Чего б ему сказать такое, чтоб он сожрал ?
IMHO значительно менее дурацкий, чем C/C++, поскольку нет строгой типизации. "типизированный указатель" это просто параноидальный бред. В PL/1 указываем волшебный режим компиляции LANGLVL(SPROG) и пишем
DCL 1 DIRBLOCK, 2 COUNT BIT(16), 2 ENTRIES CHAR(254); DCL 1 DIRENTRY BASED(DIRPTR), 2 NAME CHAR(8), 2 TTR CHAR(3), 2 C, 3 ALIAS BIT(1), 3 TTRSCOUNT BIT(2), 3 DATACOUNT BIT(5), 2 USERDATA CHAR(60); DCL DIRPTR PTR; ... DO DIRPTR = ADDR(DIRBLOCK.ENTRIES) REPEAT (DIRPTR+12+2*DATACOUNT) WHILE (DIRPTR < (ADDR(COUNT) + COUNT)); IF DIRENTRY.NAME = HIGH(8) ! DIRENTRY.NAME = LOW(8) THEN GOTO EOD; ... END; посмотрите на типы в выделенных выражениях... Компилируется и работает as a charm
IMHO значительно менее дурацкий, чем C/C++, поскольку нет строгой типизации. "типизированный указатель" это просто параноидальный бред.
Не понимаю. Кто хочет - пишет void*, а кто хочет пишет тип. Второе позволяет мне писать ptr++ , и не мучиться головой, если изменилась структура, на которую он указывает.
А вот в PLе я РЕГУЛЯРНО нарываюсь на на его идиотское умолчание для целого