Translate

Mostrar mensagens com a etiqueta Local Storage. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta Local Storage. Mostrar todas as mensagens

segunda-feira, 1 de abril de 2019

☕💥 A Jornada do Padawan COBOL – Parte 4 Desvendando o Universo dos CALLs no Mainframe

 

Bellacosa Mainframe apresenta o CALL em Cobol Parte IV

☕💥 A Jornada do Padawan COBOL – Parte 4

Desvendando o Universo dos CALLs no Mainframe

RENT, NORENT, Reentrância, Thread Safety, HEAP, STACK, CICS, LE, AMODE 31/64 e os Segredos dos Arquitetos IBM Z

Ou como descobrir que um programa COBOL pode ser executado por milhares de usuários ao mesmo tempo sem enlouquecer

Por Vagner Bellacosa – Bellacosa Mainframe


O Dia em que o Padawan descobre que o mesmo programa atende 5.000 usuários

Até agora aprendemos:

✔ Static Call

✔ Dynamic Call

✔ By Reference

✔ By Content

✔ Ponteiros

✔ CEEDUMP

✔ Troubleshooting

Mas existe uma pergunta interessante.

Como um banco consegue executar o mesmo programa COBOL para milhares de clientes simultaneamente?


O Problema

Imagine o programa:

PROGRAMA CLIENTE01

Sendo executado por:

Cliente A

Cliente B

Cliente C

Cliente D

Cliente E

...

Cliente 5.000

Ao mesmo tempo.


O pesadelo

Cliente A

Saldo = 1000

Cliente B

Saldo = 5000

Programa compartilha memória.

Resultado:

Cliente A vê saldo de B.

Cliente B recebe extrato de A.

Produção vira caos.


O conceito de Reentrância

IBM resolveu isso décadas atrás.

Criou:

RENT

Reentrant

Programa reentrante


Significa:

Código compartilhado.

Dados privados.


Visualmente


PROGRAMA COBOL

+----------------+
|     CÓDIGO     |
+----------------+
        |
        |
        |
+-------+-------+-------+

T1      T2      T3

Dados   Dados   Dados



O compilador RENT

Compilação:

RENT

ou

PROCESS(RENT)

O que muda?

Código

Read Only

Variáveis

Área privada.


Vantagens

Menos memória.

Melhor CICS.

Escalável.

Thread Safe.


O que não pode fazer?

Modificar código.

Guardar estado global.

Self-modifying.


O vilão

WORKING-STORAGE


Padawan pensa:

WS é lindo.

IBM pensa:

Depende...


Exemplo

WORKING-STORAGE.

01 WS-COUNTER PIC 9(5).

Programa chamado

100 vezes.

WS continua vivo.


Execução 1

contador=10

Execução 2

contador=11

Execução 3

contador=12


Problema em CICS.

Pode gerar corrupção.


O herói esquecido

LOCAL-STORAGE

Pouca gente usa.

IBM ama.


Exemplo

LOCAL-STORAGE.

01 LS-COUNTER PIC 9(5).

Nova chamada

Nova variável.


Execução 1

LS=0

Execução 2

LS=0

Execução 3

LS=0


Perfeito.


Thread Safety

Muito falado.

Pouco entendido.


Thread Safe significa:

Múltiplas execuções.

Mesmo código.

Sem interferência.


Java

synchronized

COBOL

RENT

LOCAL STORAGE


CICS adora RENT

CICS pode manter

programas residentes.


Exemplo

Programa

PAGO001

Carregado

Uma vez.

Usado

10 mil vezes.


CPU agradece.


NORENT

O lado sombrio.


Programa exclusivo.


Cada usuário

carrega cópia.


Visualmente

USR1


PROG



USR2


PROG



USR3


PROG

Memória explode.


Quando usar?

Batch.

Programas antigos.

Nunca em CICS.


Language Environment

LE

O grande maestro.


Controla

Heap

Stack

Exceções

Storage

Runtime


Sem LE

caos.

Com LE

harmonia.


O STACK

Pilha temporária.


CALL

Empilha.

Retorno

Desempilha.


Exemplo

MAIN

↓

A

↓

B

↓

C

STACK


C

B

A

MAIN



Volta


MAIN

Heap

Área dinâmica.


Exemplo

ALLOCATE

FREE


Muito usado

XML

JSON

APIs


Configuração

CEEOPTS

HEAP

STACK

ANYHEAP


Problema comum

Heap pequeno.


Mensagem

CEE0813S

Solução

Aumentar.


AMODE

Modo de endereçamento.


AMODE 24

16 MB


AMODE 31

2 GB


AMODE 64

Exabytes

Praticamente infinito.


Por que importa?

Grandes buffers.

Big Data.

Analytics.

IA.


Ponteiros 64 bits

Exemplo

USAGE POINTER

ou

USAGE PROCEDURE-POINTER

CALL mais rápido possível

Arquitetos IBM fazem:

Static CALL

By Reference

RENT

Local Storage

Programa residente

CICS


Resultado

Milhões de chamadas.

Baixa CPU.


Microbenchmark imaginário

Método

Tempo

Static

1 ms

Dynamic

2 ms

By Content

5 ms

Carga módulo

15 ms


Técnicas Bellacosa

Dica 1

Sempre compile RENT.


Dica 2

Evite WS temporário.


Dica 3

Prefira Local Storage.


Dica 4

Static para alta frequência.


Dica 5

Nunca abuse de By Content.


Dica 6

Documente interfaces.


Dica 7

Teste concorrência.


Easter Egg IBM

Muitos programas antigos possuem:

GO TO 999999

Ou:

ALTER

Ou:

ENTRY

Ou:

EXHIBIT

E alguns desenvolvedores mais jovens acreditam que são lendas urbanas.

Não são.

Ainda existem.

Estão em produção.

Movimentando bilhões.

E provavelmente continuarão vivos por mais tempo do que muitas aplicações modernas.


Checklist Jedi da Performance

✅ Compilar RENT

✅ Utilizar Local-Storage

✅ Minimizar By Content

✅ Reutilizar programas residentes

✅ Evitar Dynamic CALL em loops críticos

✅ Configurar HEAP adequadamente

✅ Monitorar RMF

✅ Analisar SMF 30

✅ Medir CPU

✅ Testar concorrência

✅ Validar Thread Safety


A Filosofia Jedi do CALL – Parte 4

O Padawan iniciante pensa:

O programa funciona.

O desenvolvedor intermediário pensa:

O programa funciona rápido.

O Arquiteto Mainframe entende:

O programa deve funcionar rápido, consumir pouca memória, ser reentrante, sobreviver a milhares de usuários simultâneos, ser fácil de manter e continuar executando silenciosamente por décadas.

E é exatamente por isso que alguns dos sistemas mais importantes do planeta continuam rodando em IBM Z, executando milhões de CALLs, compartilhando código reentrante, administrando HEAPs, empilhando STACKs e servindo milhares de transações por segundo, enquanto o desenvolvedor Padawan toma seu café às três da manhã e finalmente compreende que, no Mainframe, a verdadeira Força sempre esteve na gestão inteligente da memória.


Na Parte 5, o Padawan poderá explorar os segredos finais dos CALLs: Binder, Link-Edit, PDQL, RMODE, FETCH, CANCEL, Program Objects, DLLs, módulos residentes, LPA, LINKLIST, otimizações z/Architecture e as técnicas usadas pelos veteranos para reduzir microssegundos em cargas de milhões de transações.


domingo, 10 de fevereiro de 2019

☕💥 A Jornada do Padawan COBOL – Parte 2 Desvendando o Universo dos CALLs no Mainframe Parte II

 

Bellacosa Mainframe explora o comando CALL no COBOLparte II

☕💥 A Jornada do Padawan COBOL – Parte 2

Desvendando o Universo dos CALLs no Mainframe

Os Segredos de BY REFERENCE, BY CONTENT, BY VALUE, Ponteiros, Work-Storage e Local-Storage

Ou como descobrir que um simples CALL pode criar um S0C4 capaz de assombrar um desenvolvedor por semanas

Por Vagner Bellacosa – Bellacosa Mainframe


A Hora em que o Padawan descobre que CALL não é magia

Na Parte 1 descobrimos que existem dois grandes reinos:

  • Static CALL

  • Dynamic CALL

Mas ainda falta compreender algo muito mais importante.

O que realmente acontece quando passamos dados para outro programa?

Porque é aqui que nascem aproximadamente 70% dos S0C4 que já vi em produção.

E quase todos começam com uma frase inocente:

"Só acrescentei um campo..."


O Grande Segredo do COBOL

Muitos desenvolvedores vindos de Java imaginam algo parecido com:

funcao(cliente);

Criou cópia.

Passou objeto.

Garbage Collector resolve.

No Mainframe não existe fada madrinha.

Existe endereço de memória.

E apenas endereço.


O padrão COBOL

O padrão do COBOL é:

BY REFERENCE

Mesmo quando você não escreve.

CALL 'SUBPGM'
USING WS-CLIENTE.

É equivalente a:

CALL 'SUBPGM'
USING BY REFERENCE WS-CLIENTE.

Como funciona na memória

Programa principal

MAIN

00010000


WS-NOME

JOAO

CALL

Passa:

00010000

Subprograma

LINKAGE


LK-NOME

Recebe

00010000

Mesmo local.


Diagrama


MAIN


WS-NOME
+---------+
| JOAO    |
+---------+

      |
      |
      V


SUBPGM


LK-NOME


+---------+
| JOAO    |
+---------+



A magia acontece

Subrotina

MOVE 'MARIA' TO LK-NOME

Retorno

Main

MARIA

Mudou.

Porque é o mesmo endereço.


Vantagens

Muito rápido

Pouca memória

Zero cópia

Ideal tabelas grandes

VSAM

DB2

Buffers


Desvantagens

Subprograma pode destruir dados.

Sem querer.

Ou querendo.


O pesadelo do suporte

Programa A

passa saldo

Programa B

zera saldo

Programa A

grava no DB2

Cliente perde dinheiro.


O truque Jedi

Criar cópia antes.

MOVE WS-AREA TO WS-BACKUP

Quando usar

Grandes estruturas

100 mil registros

buffers VSAM

SQLDA

COMMAREA


CALL BY CONTENT

Agora o Padawan ganha maturidade.

Quer proteger dados.


Exemplo

CALL 'VALIDA'

USING
BY CONTENT WS-DATA

O compilador cria

uma área temporária.


Na memória

Original

WS-DATA


20250623

Cópia

TEMP


20250623

Subprograma recebe

TEMP


Alterações desaparecem

Subprograma

MOVE ZEROS TO LK-DATA

Volta

Main

Continua

20250623


Vantagens

Segurança

Proteção

Imutabilidade


Desvantagens

Consome memória.

Faz cópia.

CPU extra.


Benchmark imaginário

Estrutura

2 MB

1000 chamadas

By Reference

2 MB

By Content

2000 MB movimentados


O Mestre Mainframe pensa

Preciso alterar?

Não.

By Content.

Preciso compartilhar?

Reference.


CALL BY VALUE

Pouco conhecido.

Muito poderoso.


Surge com LE.

Language Environment.


Exemplo

CALL 'MINHAROT'

USING
BY VALUE WS-ID

Subrotina recebe

valor.

Não endereço.


É muito usado com

C

Assembler

LE APIs


Exemplo famoso

CALL 'CEE3ABD'

USING
BY VALUE 4095

O universo dos Ponteiros

Padawan vê isso.

USAGE POINTER

E fica com medo.

Com razão.


Exemplo

01 PTR USAGE POINTER.

Setar endereço

SET PTR TO ADDRESS OF WS-CLIENTE

PTR

00001000

Pode passar

CALL 'ROTINA'

USING PTR

Subprograma

recebe

endereço bruto.


É perigoso?

Muito.


Erro clássico

PTR inválido.

Resultado

S0C4


S0C4 explicado

CPU tenta acessar

endereço inexistente.


Exemplo

00000000

Crash.


LINKAGE SECTION

O portal interdimensional do COBOL.


Exemplo

LINKAGE SECTION.


01 LK-CLIENTE.


05 LK-NOME.


05 LK-ID.

Procedure Division

PROCEDURE DIVISION USING LK-CLIENTE.

Não aloca memória.

Nunca.


Apenas mapeia.


Work-Storage

Existe durante toda execução.


Carregado

uma vez.


Ideal

cache

tabelas

constantes


Exemplo

WORKING-STORAGE SECTION.


01 WS-CONTADOR PIC 9(9).

Local-Storage

Poucos usam.

Deveriam usar mais.


É recriado.

Toda chamada.


Exemplo

LOCAL-STORAGE SECTION.


01 LS-AREA.


05 LS-TEMP.

Diferença

WS

Persiste.

LS

Nasce.

Morre.


Exemplo

Chamada 1

contador=1

Chamada 2

contador=0


Excelente para

subrotinas reentrantes.

CICS.

LE.

Threads.


Reentrant

IBM adora isso.


Programa

não compartilha estado.


Evita corrupção.


Compilar

RENT

Erros clássicos

S0C4

Parâmetro errado


S0C7

Campo inválido


U4038

LE erro


S806

Programa não encontrado


Como validar

Antes do CALL

IF WS-PGM = SPACES

DISPLAY 'ERRO'

STOP RUN

END-IF

Conferir quantidade de parâmetros

IBM fornece

CEE3PRM

Easter Egg IBM

Muitos bancos possuem

CALL 'GENERICA'

Dentro.

EVALUATE WS-CODIGO

Mais de 300 WHEN.

Documentação

nenhuma.

Autor

aposentado em 2003.

Programa

continua funcionando.

Ninguém toca.

É conhecido como:

O Dragão Adormecido do Mainframe™


Dicas Bellacosa Mainframe

Dica 1

By Reference

90% dos casos.


Dica 2

By Content

Dados protegidos.


Dica 3

By Value

LE.

C.

Assembler.


Dica 4

Local-Storage

Muito subestimado.


Dica 5

Nunca assumir layout.

Validar tamanho.


Dica 6

Documente interfaces.

Algo parecido com:

************************************************
* ENTRADA
* CLIENTE
* DATA
*
* SAIDA
* RC
************************************************

A Filosofia Jedi do CALL – Parte 2

O Padawan iniciante pensa:

"Passar parâmetro é fácil."

O desenvolvedor intermediário pensa:

"By Reference é mais rápido."

O Mestre Mainframe entende:

"Passagem de parâmetros é um contrato binário entre programas."

E sabe que uma única alteração aparentemente inocente, como adicionar um campo em uma estrutura passada por referência, pode fazer um sistema bancário inteiro produzir S0C4, S0C7, dados corrompidos, abends misteriosos e algumas noites muito longas acompanhadas por café requentado e dumps de 500 MB.

Na próxima parte da jornada, o Padawan descobrirá os segredos de RETURN-CODE, GOBACK, STOP RUN, CEE3DMP, IPCS, CEEDUMP, rastreamento de CALLs, técnicas avançadas de troubleshooting, otimização de performance, análise de dumps e as ferramentas secretas usadas pelos Mestres Jedi do z/OS para domar os dragões da produção.


quinta-feira, 3 de janeiro de 2019

☕💥 A Jornada do Padawan COBOL – Parte 1 Desvendando o Universo dos CALLs no Mainframe

 

Bellacosa Mainframe e o CALL em programas COBOL Parte I

☕💥 A Jornada do Padawan COBOL – Parte 1

Desvendando o Universo dos CALLs no Mainframe

Ou como descobrir que chamar um programa em COBOL é quase tão importante quanto saber preparar café às 3 da manhã durante uma janela de produção

Por Vagner Bellacosa – Bellacosa Mainframe


Introdução

Todo desenvolvedor COBOL passa por um momento de iluminação.

Normalmente acontece quando ele abre um programa de produção com 30 mil linhas e encontra algo parecido com isto:

CALL 'PROG0001'
USING WS-AREA.

CALL WS-PROGRAMA
USING WS-COMMAREA.

CALL 'VALIDA01'
USING BY CONTENT WS-DATA.

CALL 'ROTINA99'
USING BY REFERENCE WS-BLOCO.

Neste momento surge a dúvida existencial:

Por que existem tantos tipos de CALL?

Qual é o mais rápido?

Qual gasta menos memória?

O que acontece dentro do z/OS?

O compilador faz mágica?

O Load Module engorda?

Como um banco executa milhões de CALLs por segundo sem explodir?

Prepare seu café.

Vamos abrir a tampa do motor do z/OS.


O que é um CALL?

Simplificando:

CALL significa pedir ajuda para outro programa.

Em vez de colocar 100 mil linhas em um único fonte, quebramos o sistema em pequenas peças reutilizáveis.

Por exemplo:

Programa principal

PROCESSA-CLIENTES

chama

VALIDA-CPF

CALCULA-JUROS

GERA-BOLETO

ENVIA-MQ

ATUALIZA-DB2

Cada um especializado.

É praticamente microserviços.

Só que inventados em 1960.


Por que IBM fez isso?

Porque memória custava uma fortuna.

Década de 70

Memória podia custar mais que um carro.

Era necessário:

reutilizar código

economizar memória

compartilhar lógica

facilitar manutenção

Assim nasceu o CALL.


Anatomia de um programa COBOL

Um programa COBOL compilado produz:

Objeto

Binder

Load Module

PDs Loadlib

Execução

Exemplo:

SYS1.LOADLIB


PROCESSA
VALIDA
JUROS
CPFCHK

O Padawan descobre o Static CALL

Exemplo

CALL 'VALIDA'

Simples.

Mas o compilador já conhece VALIDA.

Ele avisa o Binder:

Inclua VALIDA aqui.


O que acontece no LinkEdit

Binder faz:

PROCESSA


+

VALIDA


+

CPFCHK


+

JUROS


=

EXECUTÁVEL FINAL

Na memória

Antes:

PROCESSA

Depois:

PROCESSA


VALIDA


CPFCHK


JUROS

Tudo junto.

Tudo carregado.


Vantagens

Performance

Excelente.

Não precisa procurar.

Não precisa abrir bibliotecas.

Não precisa localizar módulo.

É praticamente:

BALR

Menor CPU

Menos instruções.

Menos overhead.

Menos I/O.


Desvantagens

Executável cresce.

Muito.

Exemplo

Programa principal

1 MB

Subrotinas

500 KB

Total

1,5 MB


Imagine 200 subrotinas.

Seu módulo vira um Godzilla.


Problema clássico

Padawan:

"Troquei VALIDA"

Produção:

Ainda usa antiga.

Porque precisa relinkar.


Quando usar?

Sempre que:

Programa nunca muda

Alta performance

Rotina crítica

Batch pesado

Exemplo:

Juros

Cálculo tributário

Validação interna


O Dynamic CALL aparece

Padawan evolui.

Descobre:

01 WS-PGM PIC X(8).

MOVE 'VALIDA' TO WS-PGM.

CALL WS-PGM.

O que acontece?

COBOL não sabe quem será chamado.

Somente em execução.


Busca do módulo

zOS procura:

STEPLIB

JOBLIB

LPA

LINKLIST


Exemplo

CALL CPFCHK

Sistema:

Existe?

Não.

Próximo.

Existe?

Sim.

Carrega.

Executa.


Vantagens

Flexibilidade absurda.

Pode trocar programas.

Sem recompilar.

Sem binder.

Sem relink.


Plugins COBOL

Exemplo

Cartão VISA

MOVE 'VISA0001'

Master

MOVE 'MASTER01'

PIX

MOVE 'PIX00001'

Mesmo sistema.

Rotinas diferentes.


Desvantagens

Procura programa.

Mais CPU.

Mais I/O.

Mais tempo.


Mas é lento?

Depende.

Primeira chamada.

Sim.

Segunda.

Muito rápida.

Porque pode ficar residente.


O segredo da residência

zOS é esperto.

Se programa está em memória.

Reutiliza.

Não busca novamente.


Comparação

Static

Casa própria

Dynamic

Airbnb

O executável cresce?

Static

Sim.

Dynamic

Não.

Executável principal fica pequeno.


Exemplo

Static

PROCESSA

1.5 MB

Dynamic

PROCESSA

600 KB

Subrotinas externas.


O que é mais performático?

Resposta curta.

Static.

Fim.

Mas...


O que é melhor?

Depende.

Banco.

Static.

Framework.

Dynamic.

Produtos.

Dynamic.

Rotinas financeiras.

Static.


Como o CALL funciona internamente?

Imagine isto.

Programa principal

00001000
PROCESSA

Subrotina

00025000
VALIDA

CALL executa

Guardar endereço retorno


Ir para 25000


Executar


Voltar

É praticamente um GOTO sofisticado.

Só que elegante.


Erros clássicos

S806

Programa não encontrado.

Mensagem

IEC806I

Causa

Módulo ausente.

STEPLIB errada.

Nome inválido.


S0C1

Executou lixo.

Programa corrompido.


S0C4

Endereço inválido.

Muito comum em parâmetros errados.


Como descobrir

SDSF

JESMSGLG

SYSOUT


Verificar:

STEPLIB

SYSLIB

LOADLIB


Easter Egg IBM

Muitos bancos possuem:

PROG0001

PROG0002

PROG0003

Ninguém sabe o que fazem.

Autor aposentou em 1998.

Documentação desapareceu.

Programa continua funcionando.

Todos têm medo de alterar.

É chamado:

Código Arqueológico Mainframe™


Dicas Bellacosa Mainframe

Dica 1

Static para alta frequência.


Dica 2

Dynamic para produtos.


Dica 3

Nunca fazer:

MOVE WS-USUARIO TO WS-PGM

CALL WS-PGM

Sem validar.

Pode chamar qualquer coisa.

Inclusive algo inexistente.


Dica 4

Validar sempre.

EVALUATE WS-PGM

WHEN 'CPFCHK'

WHEN 'JUROS01'

WHEN 'PIX0001'

WHEN OTHER

DISPLAY 'INVALIDO'

END-EVALUATE

Dica 5

Logar chamadas.

DISPLAY 'CALL=' WS-PGM

Ajuda muito.


A Filosofia Jedi do CALL

O Padawan iniciante pensa:

CALL serve apenas para executar outro programa.

O desenvolvedor intermediário pensa:

CALL serve para reutilizar código.

O Mestre Mainframe entende:

CALL é uma decisão arquitetural.

Ele impacta:

  • CPU

  • Memória

  • Tempo de resposta

  • Tamanho do Load Module

  • Facilidade de manutenção

  • Segurança

  • Escalabilidade

  • Observabilidade

  • Estratégia de deploy

E é exatamente por isso que, cinquenta anos depois, os sistemas bancários que movimentam bilhões de dólares diariamente ainda utilizam a mesma instrução COBOL que um programador digitou em um terminal verde na década de 1970:

CALL 'SUBPGM'

Na próxima etapa da jornada, o Padawan descobrirá que o verdadeiro poder do COBOL não está apenas em chamar programas, mas em como os dados atravessam a fronteira entre eles, mergulhando nos mistérios de BY REFERENCE, BY CONTENT, BY VALUE, ponteiros, Work-Storage, Local-Storage e Language Environment, onde vivem os temidos S0C4, os buffers compartilhados e os segredos que fazem alguns programas parecerem mágicos aos olhos dos desenvolvedores mais jovens.