Re: Best practice for 24-bit storage in assembler called from C/C++
Shmuel Metz (Seymour J.) wrote: In 4b8389b7.9030...@gmail.com, on 02/23/2010 at 03:54 PM, David Crayford dcrayf...@gmail.com said: You're fundamentally not reentrant if you use any kind of global data. Nonsense. You're reentrant as long as you ensure that concurrent access doesn't cause incorrect results. The simplest example is a routine that keeps a counter in CVTUSER and uses CS to serialize the access. There's plenty of code in z/OS that uses global data, although the serialization is typically more complicated, involving, e.g., ENQ, latches, PLO. Since your talking about concurrency let's take the C global errno as an example. Not too crash hot when it comes to multi-threaded programs. That's where TLS (thread local storage) comes to the rescue. Why lock when you have local storage? -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
--snip--- If you've ever done list processing, CONTROLLED storage is the cat's meow. Beats the Dickens out of trying to maintain arrays and array counters, especially if there's a chance of exceeding the size of the arrays. ... How is CONTROLLED preferable to BASED? Certinly not if you need to delete arbitrary list elements, since (I just RTFM) CONTROLLED is strictly LIFO. ---unsnip--- In order to do proper list processing, you need to define the elements CONTROLLED BASED(..). But the original question was about CONTROLLED. Rick -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
In 4b86718e.3070...@gmail.com, on 02/25/2010 at 08:48 PM, David Crayford dcrayf...@gmail.com said: Since your talking about concurrency let's take the C global errno as an example. Not too crash hot when it comes to multi-threaded programs. That's where TLS (thread local storage) comes to the rescue. Why lock when you have local storage? There are issues with thread safety in C. You lock either because you are doing something that intrinsically requires shared data or because a clumsy facility forces you to share data; in either case you have to serialize to preserve reentrancy. For things where it is possible to have thread local instances, there's no need to lock. -- Shmuel (Seymour J.) Metz, SysProg and JOAT ISO position; see http://patriot.net/~shmuel/resume/brief.html We don't care. We don't have to care, we're Congress. (S877: The Shut up and Eat Your spam act of 2003) -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
-Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of john gilmore Sent: Tuesday, February 23, 2010 1:02 PM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ Snipped The absence of this facility from C--Dennis Ritchie did not understand what controlled storage was for--is the reason for all the ugliness of multiple copies of writable static in C. OK, I'll bite. What is/was the intended purpose of controlled storage? I remember when I first was learning PL/1 (too many moons ago to count) being fascinated by it, but at that time I couldn't really see what the advantage(s) of controlled storage over based storage were. Than I had to move on to a non-PL/1 shop and I kind of lost track of it. TIA for curing my ignorance. Peter This message and any attachments are intended only for the use of the addressee and may contain information that is privileged and confidential. If the reader of the message is not the intended recipient or an authorized representative of the intended recipient, you are hereby notified that any dissemination of this communication is strictly prohibited. If you have received this communication in error, please notify us immediately by e-mail and delete the message and any attachments from your system. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
In a6b9336cdb62bb46b9f8708e686a7ea005bde01...@nrhmms8p02.uicnrh.dom, on 02/22/2010 at 12:15 PM, McKown, John john.mck...@healthmarkets.com said: There is a very old, very terrible technique that I used long ago. I mention it, but do not recommend it. From the currently executing TCB, find the job step TCB (JSTCB). Pick up the TCBFSA pointer from that TCB, which is a pointer to the first save area. Use the word at offset +0 to hold your pointer. Like may other clever mechanisms, it works fine when you are the only one to use it and becomes interesting as soon as two independent pieces of code use it. But it's not my dog. -- Shmuel (Seymour J.) Metz, SysProg and JOAT ISO position; see http://patriot.net/~shmuel/resume/brief.html We don't care. We don't have to care, we're Congress. (S877: The Shut up and Eat Your spam act of 2003) -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
In 4b8389b7.9030...@gmail.com, on 02/23/2010 at 03:54 PM, David Crayford dcrayf...@gmail.com said: You're fundamentally not reentrant if you use any kind of global data. Nonsense. You're reentrant as long as you ensure that concurrent access doesn't cause incorrect results. The simplest example is a routine that keeps a counter in CVTUSER and uses CS to serialize the access. There's plenty of code in z/OS that uses global data, although the serialization is typically more complicated, involving, e.g., ENQ, latches, PLO. -- Shmuel (Seymour J.) Metz, SysProg and JOAT ISO position; see http://patriot.net/~shmuel/resume/brief.html We don't care. We don't have to care, we're Congress. (S877: The Shut up and Eat Your spam act of 2003) -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
In listserv%201002221028079631.0...@bama.ua.edu, on 02/22/2010 at 10:28 AM, Paul Gilmartin paulgboul...@aim.com said: Only if you're not authorized. When did that form of IDENTIFY start requiring APF authorization? I agree that the overhead might be higher with IDENTIFY. -- Shmuel (Seymour J.) Metz, SysProg and JOAT ISO position; see http://patriot.net/~shmuel/resume/brief.html We don't care. We don't have to care, we're Congress. (S877: The Shut up and Eat Your spam act of 2003) -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
In 053f2631ec9c584883847c8b4970a22806287...@josqems1.jsq.bsg.ad.adp.com, on 02/24/2010 at 11:57 AM, Farley, Peter x23353 peter.far...@broadridge.com said: OK, I'll bite. What is/was the intended purpose of controlled storage? Stack. but at that time I couldn't really see what the advantage(s) of controlled storage over based storage were. It's like the advantage of a screwdriver over a hammer; they're designed for different tasks. -- Shmuel (Seymour J.) Metz, SysProg and JOAT ISO position; see http://patriot.net/~shmuel/resume/brief.html We don't care. We don't have to care, we're Congress. (S877: The Shut up and Eat Your spam act of 2003) -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
In 022901cab4a7$a821dc90$f86595...@org, on 02/23/2010 at 08:45 AM, Charles Mills charl...@mcn.org said: FOO DXD F BAR DC Q(FOO) does that give me a fullword that will be task-unique at run time? No. But if in the same load module you do the above and Joe does MYFOO DXD A MYBAR DC Q(MYFOO) then BAR and MYVAR will have different contents. In really old PL/I compilers IBM put the Q-cons in the offset fields of instructions, limiting the PRV to 4096 bytes. Will GETMAIN ... LR2,BAR Point to unique storage pointer ST R1,0(,R2) Save my storage area for subsequent use do what the comments say it does? No. But if PRVREG points to srage allocated with a length from a CXD, then GETMAIN ... LR2,BAR Point to unique offset ST R1,0(PTVTRG,R2) Save my storage area for subsequent use will do what the comments say it does. However, Don's suggestion (CEEPDDA and CEEPLDA) is probably the best way to go. -- Shmuel (Seymour J.) Metz, SysProg and JOAT ISO position; see http://patriot.net/~shmuel/resume/brief.html We don't care. We don't have to care, we're Congress. (S877: The Shut up and Eat Your spam act of 2003) -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
In 00ab01cab3d9$9d328790$d79796...@org, on 02/22/2010 at 08:10 AM, Charles Mills charl...@mcn.org said: IDENTIFY is an interesting idea. I would suspect lower overhead than name/token. But can you IDENTIFY an address in GETMAIN storage? Yes. have to be inside a real load module? No. -- Shmuel (Seymour J.) Metz, SysProg and JOAT ISO position; see http://patriot.net/~shmuel/resume/brief.html We don't care. We don't have to care, we're Congress. (S877: The Shut up and Eat Your spam act of 2003) -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
snip--- OK, I'll bite. What is/was the intended purpose of controlled storage? I remember when I first was learning PL/1 (too many moons ago to count) being fascinated by it, but at that time I couldn't really see what the advantage(s) of controlled storage over based storage were. Than I had to move on to a non-PL/1 shop and I kind of lost track of it. --unsnip If you've ever done list processing, CONTROLLED storage is the cat's meow. Beats the Dickens out of trying to maintain arrays and array counters, especially if there's a chance of exceeding the size of the arrays. I once updated GETMAIN/FREEMAIN in OS/360 to keep all FQE's in ascending order by size, and merging adjacent free areas into a single larger area. (Re-invented the wheel there.) I've also used list processing and CONTROLLED storage in processing VTOC data. Makes sorting really easy, since all my insertions were made in collating sequence. Somewhere I've still got some nifty, but old, macros for list processing in Assembler. Rick -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
On Wed, 24 Feb 2010 16:29:52 -0500, Shmuel Metz (Seymour J.) wrote: then BAR and MYVAR will have different contents. In really old PL/I compilers IBM put the Q-cons in the offset fields of instructions, limiting the PRV to 4096 bytes. That's why there's a 12-bit (IIRC) RLD! -- gil -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
On Wed, 24 Feb 2010 16:55:22 -0600, Rick Fochtman wrote: If you've ever done list processing, CONTROLLED storage is the cat's meow. Beats the Dickens out of trying to maintain arrays and array counters, especially if there's a chance of exceeding the size of the arrays. ... How is CONTROLLED preferable to BASED? Certinly not if you need to delete arbitrary list elements, since (I just RTFM) CONTROLLED is strictly LIFO. -- gil -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
On Mon, 22 Feb 2010 16:58:04 -0800 Charles Mills charl...@mcn.org wrote: : Don't you want to leave the DCB open between calls? :No If you are opening the DCB for each call requiring LOC=BELOW the GETMAIN/FREEMAIN overhead would not even be recognized. :-Original Message- :From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf :Of Shmuel Metz (Seymour J.) :Sent: Monday, February 22, 2010 8:35 AM :To: IBM-MAIN@bama.ua.edu :Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ :In 003c01cab362$c950c0c0$5bf242...@org, on 02/21/2010 : at 06:00 PM, Charles Mills charl...@mcn.org said: :Subject: Best practice for 24-bit storage in assembler called from C/C++ :Best practice is for new code to be refreshable and reentrant. :I'm writing a fairly large MVS batch application in C++. At several :points it is necessary to call library type routines that I am writing :in assembler. Several of the routines (unfortunately) need to use QSAM :macros and so need below-the-line storage. :The issues are the same whether the storage is above the line or below. :Obviously I could do a GETMAIN or STORAGE OBTAIN LOC=24 on the way in :and FREEMAIN or STORAGE RELEASE on the way out. :Don't you want to leave the DCB open between calls? :I could make the calling C++ responsible for providing a work area :obtained with _malloc24(). But I don't like that for aesthetic reasons :- :violates encapsulation, making the caller responsible for the inner :workings of the called function. :Not if that storage is a black box. :Is there a better way? :Does LE use a CXD to allocate a pseudo-register vector? :Is there some LE-supported solution to the whole problem, such as a :below the line stack feature -- Binyamin Dissen bdis...@dissensoftware.com http://www.dissensoftware.com Director, Dissen Software, Bar Grill - Israel Should you use the mailblocks package and expect a response from me, you should preauthorize the dissensoftware.com domain. I very rarely bother responding to challenge/response systems, especially those from irresponsible companies. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
In article 4b8389b7.9030...@gmail.com you wrote: Charles Mills wrote: The fundamental problem I guess is that any solution that keeps a pointer around somewhere in the code is fundamentally not reentrant, unless I can figure out how to utilize pseudo-registers. I've heard the term pseudo-register for years but I have never delved into them. Perhaps now is the time. You're fundamentally not reentrant if you use any kind of global data. That may be name/tokens, control block anchors or WSA. That may not be a problem for you if you only want one instance of the routine. I prefer to design C++ applications to use objects which can handle multiple instantiations of the same class even if I only need one instance. You never know when that requirement may change. The purpose of WSA is to provide reentrancy. Every copy of the program will get it's own WSA initialised when the program starts. No different than in assembler where you do a GETMAIN and use MF=L macros. RELATED: is anyone using void *__malloc24(size_t size);? If you code it then it does not compile; if you code your own declaration then it does not link. At least not in my code. Yes, I included stdlib.h. Obviously, not a big deal to write an assembler GETMAIN routine, but still ... Charles -- Don Poitras - SAS Development - SAS Institute Inc. - SAS Campus Drive sas...@sas.com (919) 531-5637Cary, NC 27513 -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
On Tue, Feb 23, 2010 at 12:07 PM, Don Poitras poit...@pobox.com wrote: In article 4b8389b7.9030...@gmail.com you wrote: Charles Mills wrote: The fundamental problem I guess is that any solution that keeps a pointer around somewhere in the code is fundamentally not reentrant, unless I can figure out how to utilize pseudo-registers. I've heard the term pseudo-register for years but I have never delved into them. Perhaps now is the time. You're fundamentally not reentrant if you use any kind of global data. That may be name/tokens, control block anchors or WSA. That may not be a problem for you if you only want one instance of the routine. I prefer to design C++ applications to use objects which can handle multiple instantiations of the same class even if I only need one instance. You never know when that requirement may change. The purpose of WSA is to provide reentrancy. Every copy of the program will get it's own WSA initialised when the program starts. No different than in assembler where you do a GETMAIN and use MF=L macros. This really depends on how you get access to the program with the WSA. If you load a program once and put the address in commonly retrievable area (vector table, name/token pair, etc.) then WSA does not provide reentrancy. RELATED: is anyone using void *__malloc24(size_t size);? If you code it then it does not compile; if you code your own declaration then it does not link. At least not in my code. Yes, I included stdlib.h. Obviously, not a big deal to write an assembler GETMAIN routine, but still ... Charles -- Don Poitras - SAS Development - SAS Institute Inc. - SAS Campus Drive sas...@sas.com (919) 531-5637Cary, NC 27513 -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
The C/C++ runtime library reference clearly states LP64 Not my copy. I am looking at the full page (PDF) and 64 does not appear anywhere on the page. I would paste it here but I suspect I would lose so much formatting that it would be pointless. SA22-7821-10 page 1181. (Printed page number 1181, not PDF internal page 1181.) SA22-7821-10 is a year and a half old but it seems to be what the Softcopy Librarian thought was the latest and greatest as of about a month or two ago. Charles -Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of David Crayford Sent: Monday, February 22, 2010 11:49 PM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ Charles Mills wrote: __malloc24 were intended to be used by LP64 callers Does that make any sense? Only a 64 bit user would want below the 16 MB line storage? And did they ever consider documenting this? They did. The C/C++ runtime library reference clearly states LP64. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
Don Poitras wrote: In article 4b8389b7.9030...@gmail.com you wrote: Charles Mills wrote: The fundamental problem I guess is that any solution that keeps a pointer around somewhere in the code is fundamentally not reentrant, unless I can figure out how to utilize pseudo-registers. I've heard the term pseudo-register for years but I have never delved into them. Perhaps now is the time. You're fundamentally not reentrant if you use any kind of global data. That may be name/tokens, control block anchors or WSA. That may not be a problem for you if you only want one instance of the routine. I prefer to design C++ applications to use objects which can handle multiple instantiations of the same class even if I only need one instance. You never know when that requirement may change. The purpose of WSA is to provide reentrancy. Every copy of the program will get it's own WSA initialised when the program starts. No different than in assembler where you do a GETMAIN and use MF=L macros. The purpose of WSA is to provide constructed reentrancy for main programs that may in common storage like LPA. As a programming model it's global data. Global data is questionable in good design if you can avoid it. RELATED: is anyone using void *__malloc24(size_t size);? If you code it then it does not compile; if you code your own declaration then it does not link. At least not in my code. Yes, I included stdlib.h. Obviously, not a big deal to write an assembler GETMAIN routine, but still ... Charles -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
Charles, Have you looked at the ALL31(OFF) LE option? I don't know how it works for C/C++ but for Cobol this option instructs LE to allocate the COBOL EXTERNAL data in storage below the line. Which means if a main program defines an EXTERNAL variable it will be below the line AND accessible by the name from any subroutine that also defines it as EXTERNAL. This is a rather old trick and so the most current LE may have other options to suit your needs. HTH, -Victor- This message and any attachments are intended only for the use of the addressee and may contain information that is privileged and confidential. If the reader of the message is not the intended recipient or an authorized representative of the intended recipient, you are hereby notified that any dissemination of this communication is strictly prohibited. If you have received this communication in error, please notify us immediately by e-mail and delete the message and any attachments from your system. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
In article 4e2421a41002230531i1d252a29n484a6c323ae9b...@mail.gmail.com you wrote: On Tue, Feb 23, 2010 at 12:07 PM, Don Poitras poit...@pobox.com wrote: In article 4b8389b7.9030...@gmail.com you wrote: Charles Mills wrote: The fundamental problem I guess is that any solution that keeps a pointer around somewhere in the code is fundamentally not reentrant, unless I can figure out how to utilize pseudo-registers. I've heard the term pseudo-register for years but I have never delved into them. Perhaps now is the time. You're fundamentally not reentrant if you use any kind of global data. That may be name/tokens, control block anchors or WSA. That may not be a problem for you if you only want one instance of the routine. I prefer to design C++ applications to use objects which can handle multiple instantiations of the same class even if I only need one instance. You never know when that requirement may change. The purpose of WSA is to provide reentrancy. Every copy of the program will get it's own WSA initialised when the program starts. No different than in assembler where you do a GETMAIN and use MF=L macros. This really depends on how you get access to the program with the WSA. If you load a program once and put the address in commonly retrievable area (vector table, name/token pair, etc.) then WSA does not provide reentrancy. We're back to talking about something other than batch programs. The OP wasn't asking to write a system service, just a job that builds a DCB in assembler. -- Don Poitras - SAS Development - SAS Institute Inc. - SAS Campus Drive sas...@sas.com (919) 531-5637Cary, NC 27513 -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
Let me come right out and say I am asking a potentially dumb question here. I freely admit I have never used pseudo-registers or any of the associated features. (Level set: yes, I am totally familiar with the meaning of reentrant and reusable and have coded lots of do-it-yourself reentrant code in 360+ assembler.) Why am I asking a dumb question here? Because I don't see much if any overview of the topic in the docs, just detail instruction documentation, and I don't know where else to turn. If anyone could suggest a source for an education in pseudo-registers and related features, I'm all ears. Does DXD help solve this problem? If I code FOO DXD F BAR DC Q(FOO) does that give me a fullword that will be task-unique at run time? Will GETMAIN ... LR2,BAR Point to unique storage pointer ST R1,0(,R2) Save my storage area for subsequent use do what the comments say it does? Is this code -- assuming the usual other requirements are met -- satisfy reentrancy? Or am I off base? Environment: Pre-linker, PDS, and OS linkage from LE C. Why pre-linker and not binder/PDSE? Two reasons: trying to solve one learning curve at a time, and hoping to avoid PDSEs because of all of the customer resistance reasons mentioned in a recent thread on IBMMAIN. (Please don't try to convince me that PDSEs are cool. I have no personal problem with them. I am in the software product business, and the customer objections are a fact, even if some think they are baseless. You don't sell software by arguing with the prospects.) Charles -Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of Don Poitras Sent: Tuesday, February 23, 2010 8:22 AM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ This really depends on how you get access to the program with the WSA. If you load a program once and put the address in commonly retrievable area (vector table, name/token pair, etc.) then WSA does not provide reentrancy. We're back to talking about something other than batch programs. The OP wasn't asking to write a system service, just a job that builds a DCB in assembler. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
I used pseudo registers extensively a long, long time ago, but not recently so I'm very rusty on it. However, I think you also need a CXD instruction which will define a fullword into which the linkeditor (or binder, I suppose) will put the cumulative length of everything referenced in a QCON. At initialization you do a getmain for the value in the CXD fullword. Later, when you want the address of one of your areas, you load the QCON and use it as an offset into the gotten storage. IMHO, using DXDs for each field is not the way to go. Rather, referring to a DSECT in a QCON will give you the offset to the entire DSECT within the gotten storage. Date: Tue, 23 Feb 2010 08:45:49 -0800 From: charl...@mcn.org Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ To: IBM-MAIN@bama.ua.edu Let me come right out and say I am asking a potentially dumb question here. I freely admit I have never used pseudo-registers or any of the associated features. (Level set: yes, I am totally familiar with the meaning of reentrant and reusable and have coded lots of do-it-yourself reentrant code in 360+ assembler.) Why am I asking a dumb question here? Because I don't see much if any overview of the topic in the docs, just detail instruction documentation, and I don't know where else to turn. If anyone could suggest a source for an education in pseudo-registers and related features, I'm all ears. Does DXD help solve this problem? If I code FOO DXD F BAR DC Q(FOO) does that give me a fullword that will be task-unique at run time? Will GETMAIN ... L R2,BAR Point to unique storage pointer ST R1,0(,R2) Save my storage area for subsequent use do what the comments say it does? Is this code -- assuming the usual other requirements are met -- satisfy reentrancy? Or am I off base? Environment: Pre-linker, PDS, and OS linkage from LE C. Why pre-linker and not binder/PDSE? Two reasons: trying to solve one learning curve at a time, and hoping to avoid PDSEs because of all of the customer resistance reasons mentioned in a recent thread on IBMMAIN. (Please don't try to convince me that PDSEs are cool. I have no personal problem with them. I am in the software product business, and the customer objections are a fact, even if some think they are baseless. You don't sell software by arguing with the prospects.) Charles _ Hotmail: Powerful Free email with security by Microsoft. http://clk.atdmt.com/GBL/go/201469230/direct/01/ -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
You will need several DXDs and a single CXD. This machinery was devised originally for PL/I, but its use outside PL/I is fully supported by both the HLASM and the Linker. That said, the best documentation for it is in the old PL/I Optimizing Compiler manuals. (The PL/I Optimizing Compiler was not OCO; the current, Enterprise compiler is.) If you can get your hands on either an old Program Logic Manual, usually referred by its obvious acronym, as a PLM, or only a little less satisfactory, an old Execution Logic Manual, usually referred to for consistency as just an EL, for this compiler you will find lucid explanations of their implementation and use in either or both. The absence of this facility from C--Dennis Ritchie did not understand what controlled storage was for--is the reason for all the ugliness of multiple copies of writable static in C. John Gilmore Ashland, MA 01721-1817 USA _ Your E-mail and More On-the-Go. Get Windows Live Hotmail Free. http://clk.atdmt.com/GBL/go/201469229/direct/01/ -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
Thanks, John. That was my recollection -- that this feature was originally for PL/I. As luck would have it I am working with (not developing using -- don't ask) OS PL/I V2R3. I have the user documentation but not the PLMs (I'm familiar with the acronym). Any further pointers will be appreciated. Charles -Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of john gilmore Sent: Tuesday, February 23, 2010 10:02 AM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ You will need several DXDs and a single CXD. This machinery was devised originally for PL/I, but its use outside PL/I is fully supported by both the HLASM and the Linker. That said, the best documentation for it is in the old PL/I Optimizing Compiler manuals. (The PL/I Optimizing Compiler was not OCO; the current, Enterprise compiler is.) If you can get your hands on either an old Program Logic Manual, usually referred by its obvious acronym, as a PLM, or only a little less satisfactory, an old Execution Logic Manual, usually referred to for consistency as just an EL, for this compiler you will find lucid explanations of their implementation and use in either or both. The absence of this facility from C--Dennis Ritchie did not understand what controlled storage was for--is the reason for all the ugliness of multiple copies of writable static in C. John Gilmore Ashland, MA 01721-1817 USA _ Your E-mail and More On-the-Go. Get Windows Live Hotmail Free. http://clk.atdmt.com/GBL/go/201469229/direct/01/ -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
My thought was not to use the DXD for the bulk of the gotten storage but rather just for a pointer to an area of 24-bit storage that I would manage using traditional assembler techniques. I just need one word! My kingdom for a word! I kind of get pseudoregisters I think. The idea is that you can write a bunch of disjoint DSECTs and the compilers and binder will essentially assemble them all into one big area, and tell you at run time the total size (in a CXD) and the offset of each DSECT (in a Q con) within the conglomeration. Coding DXD F is kind of like coding a one-word DSECT -- not wrong but not very efficient use of source code. I guess the fundamental question is this: will something outside of my code give me that one task-unique word? I am beginning to think it will not. The problem pseudo-registers seem to solve is one GETMAIN for many DSECTs -- even across separate compilation units -- not give me some task-unique storage. I keep coming back to the same problem: there's no way anything stored inside your code could possibly be reentrant-task-unique. I think I am down to one of two fairly ugly solutions: passing the storage in from the C++ caller -- made more ugly by the fact that __malloc24() is dysfunctional -- the C code is going to have to get the storage from assembler in order to be able to give it to assembler; or using the word zero of the first save area solution. The last time I did a library like this, the calling language was Rexx, and Rexx provides an anchor word that it passes to called routines. That feature makes this problem trivial. Let me repeat a question from the original post: What is CEECAA_TCASRV_USERWORD for? Where is it documented? Charles -Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of J R Sent: Tuesday, February 23, 2010 9:55 AM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ I used pseudo registers extensively a long, long time ago, but not recently so I'm very rusty on it. However, I think you also need a CXD instruction which will define a fullword into which the linkeditor (or binder, I suppose) will put the cumulative length of everything referenced in a QCON. At initialization you do a getmain for the value in the CXD fullword. Later, when you want the address of one of your areas, you load the QCON and use it as an offset into the gotten storage. IMHO, using DXDs for each field is not the way to go. Rather, referring to a DSECT in a QCON will give you the offset to the entire DSECT within the gotten storage. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
On Tue, 23 Feb 2010 18:01:57 +, john gilmore wrote: If you can get your hands on either an old Program Logic Manual, usually referred by its obvious acronym, as a PLM, or only a little less satisfactory, an old Execution Logic Manual, usually referred to for consistency as just an EL, for this compiler you will find lucid explanations of their implementation and use in either or both. Thank you, John. The EL can be found at http://www.bitsavers.org/pdf/ibm/370/pli/SC33-0025-3_PLI_Optimizing_Compiler_Execution_Logic_Sep85.pdf Tiny: http://tinyurl.com/yg985lp -- Tom Marchant -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
or using the word zero of the first save area solution. I know you said you didn't want to keep the DCB open across calls and that may be why you ignored my suggestion. In case you didn't see it, I'll repeat it here: If you are going to keep the DCB open across calls you could: - extend your DCB with the rest of your information, i.e. make the DCB the first part of your control block. - when called, run the DEB queue until you find the one that points back to your DCB which you can identify/verify from the rest of your control block. The last time I used this method, and pseudo registers, was in the '70s. It's possible I'm misremembering but I think it worked well at the time. I have also used the FSA word0 method many times in the past. Date: Tue, 23 Feb 2010 10:38:39 -0800 From: charl...@mcn.org Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ To: IBM-MAIN@bama.ua.edu My thought was not to use the DXD for the bulk of the gotten storage but rather just for a pointer to an area of 24-bit storage that I would manage using traditional assembler techniques. I just need one word! My kingdom for a word! I kind of get pseudoregisters I think. The idea is that you can write a bunch of disjoint DSECTs and the compilers and binder will essentially assemble them all into one big area, and tell you at run time the total size (in a CXD) and the offset of each DSECT (in a Q con) within the conglomeration. Coding DXD F is kind of like coding a one-word DSECT -- not wrong but not very efficient use of source code. I guess the fundamental question is this: will something outside of my code give me that one task-unique word? I am beginning to think it will not. The problem pseudo-registers seem to solve is one GETMAIN for many DSECTs -- even across separate compilation units -- not give me some task-unique storage. I keep coming back to the same problem: there's no way anything stored inside your code could possibly be reentrant-task-unique. I think I am down to one of two fairly ugly solutions: passing the storage in from the C++ caller -- made more ugly by the fact that __malloc24() is dysfunctional -- the C code is going to have to get the storage from assembler in order to be able to give it to assembler; or using the word zero of the first save area solution. The last time I did a library like this, the calling language was Rexx, and Rexx provides an anchor word that it passes to called routines. That feature makes this problem trivial. Let me repeat a question from the original post: What is CEECAA_TCASRV_USERWORD for? Where is it documented? Charles -Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of J R Sent: Tuesday, February 23, 2010 9:55 AM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ I used pseudo registers extensively a long, long time ago, but not recently so I'm very rusty on it. However, I think you also need a CXD instruction which will define a fullword into which the linkeditor (or binder, I suppose) will put the cumulative length of everything referenced in a QCON. At initialization you do a getmain for the value in the CXD fullword. Later, when you want the address of one of your areas, you load the QCON and use it as an offset into the gotten storage. IMHO, using DXDs for each field is not the way to go. Rather, referring to a DSECT in a QCON will give you the offset to the entire DSECT within the gotten storage. _ Hotmail: Trusted email with powerful SPAM protection. http://clk.atdmt.com/GBL/go/201469227/direct/01/ -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
-Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of Charles Mills Sent: Tuesday, February 23, 2010 1:39 PM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ Snipped Let me repeat a question from the original post: What is CEECAA_TCASRV_USERWORD for? Where is it documented? 2.2.5.22 CEE3USR--Set or query user area fields Documented in the LE Language Environment Programming Reference here (watch wrap): http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/CEEA3190/2.2. 5.22?SHELF=CEE2BK90DT=20080615233920 HTH Peter This message and any attachments are intended only for the use of the addressee and may contain information that is privileged and confidential. If the reader of the message is not the intended recipient or an authorized representative of the intended recipient, you are hereby notified that any dissemination of this communication is strictly prohibited. If you have received this communication in error, please notify us immediately by e-mail and delete the message and any attachments from your system. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
Thanks. There is no one DCB that is consistently open across all calls -- actually none that are open across any two calls as of this moment -- but it's a clever idea. I will keep it in mind. Charles -Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of J R Sent: Tuesday, February 23, 2010 11:04 AM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ or using the word zero of the first save area solution. I know you said you didn't want to keep the DCB open across calls and that may be why you ignored my suggestion. In case you didn't see it, I'll repeat it here: If you are going to keep the DCB open across calls you could: - extend your DCB with the rest of your information, i.e. make the DCB the first part of your control block. - when called, run the DEB queue until you find the one that points back to your DCB which you can identify/verify from the rest of your control block. The last time I used this method, and pseudo registers, was in the '70s. It's possible I'm misremembering but I think it worked well at the time. I have also used the FSA word0 method many times in the past. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
On 23 February 2010 13:38, Charles Mills charl...@mcn.org wrote: I kind of get pseudoregisters I think. The idea is that you can write a bunch of disjoint DSECTs and the compilers and binder will essentially assemble them all into one big area, and tell you at run time the total size (in a CXD) and the offset of each DSECT (in a Q con) within the conglomeration. Coding DXD F is kind of like coding a one-word DSECT -- not wrong but not very efficient use of source code. I guess the fundamental question is this: will something outside of my code give me that one task-unique word? I am beginning to think it will not. The problem pseudo-registers seem to solve is one GETMAIN for many DSECTs -- even across separate compilation units -- not give me some task-unique storage. I keep coming back to the same problem: there's no way anything stored inside your code could possibly be reentrant-task-unique. Right - the Binder (and its several deprecated friends) will not magically obtain your task-unique word. But LE will, and with C++ you are anyway running in an LE world. Check out the Anchor Support section, chapter 15 in, of all user-friendly places, the Language Environment Vendor Interfaces book. Lots of interesting stuff in there, much of which probably should be in the mainstream books. Tony H. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
David, what's the name/location of the IBM C/C++ forum? Thanks! -- Regards, Gord Tomlin Action Software International (a division of Mazda Computer Corporation) Tel: (905) 470-7113, Fax: (905) 470-6507 David Crayford wrote: They did. The C/C++ runtime library reference clearly states LP64. It's obviously a design error because it's a crazy restriction. If Kelly Arrey is watching maybe she can set the wheels in motion to changing it. Otherwise there is an IBM C/C++ forum where you can make your grievances known. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
Lots of interesting stuff in there, much of which probably should be in the mainstream books. Roger that -- both of your points. Charles -Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of Tony Harminc Sent: Tuesday, February 23, 2010 2:54 PM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ On 23 February 2010 13:38, Charles Mills charl...@mcn.org wrote: I guess the fundamental question is this: will something outside of my code give me that one task-unique word? I am beginning to think it will not. The problem pseudo-registers seem to solve is one GETMAIN for many DSECTs -- even across separate compilation units -- not give me some task-unique storage. I keep coming back to the same problem: there's no way anything stored inside your code could possibly be reentrant-task-unique. Check out the Anchor Support section, chapter 15 in, of all user-friendly places, the Language Environment Vendor Interfaces book. Lots of interesting stuff in there, much of which probably should be in the mainstream books. Tony H. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
Thanks all. All things considered, I think I am going to use the word 0 of the first save area technique. I will put a pointer to my BTL storage directly there, but I will reserve the first few words for additional pointers just in case a need arises. I will put an eyecatcher on the front, and I will check for 0 in the word before initializing it, and check for my eyecatcher before using the address value. Probably do a single GETMAIN, but make one of the first few words point to the main part of the area so that there is compatibility with a different allocation scheme going forward. CEE3USR and CEEARLU are close runners-up. Looking at them more closely will be my fallback if I get worried about the robustness of the above technique. Thanks again. Great resource. Charles -Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of Tony Harminc Sent: Tuesday, February 23, 2010 2:54 PM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ On 23 February 2010 13:38, Charles Mills charl...@mcn.org wrote: I kind of get pseudoregisters I think. The idea is that you can write a bunch of disjoint DSECTs and the compilers and binder will essentially assemble them all into one big area, and tell you at run time the total size (in a CXD) and the offset of each DSECT (in a Q con) within the conglomeration. Coding DXD F is kind of like coding a one-word DSECT -- not wrong but not very efficient use of source code. I guess the fundamental question is this: will something outside of my code give me that one task-unique word? I am beginning to think it will not. The problem pseudo-registers seem to solve is one GETMAIN for many DSECTs -- even across separate compilation units -- not give me some task-unique storage. I keep coming back to the same problem: there's no way anything stored inside your code could possibly be reentrant-task-unique. Right - the Binder (and its several deprecated friends) will not magically obtain your task-unique word. But LE will, and with C++ you are anyway running in an LE world. Check out the Anchor Support section, chapter 15 in, of all user-friendly places, the Language Environment Vendor Interfaces book. Lots of interesting stuff in there, much of which probably should be in the mainstream books. Tony H. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
On Tue, 23 Feb 2010 18:01:57 +, john gilmore wrote: You will need several DXDs and a single CXD. ... The absence of this facility from C--Dennis Ritchie did not understand what controlled storage was for--is the reason for all the ugliness of multiple copies of writable static in C. It is conventional in C to be able to have writable static storage statically initialized piecewise from multiple translation units. Such initialization is effective even before the relevant translation unit has been entered by a call. The ugliness arises when one attempts to accomplish this with pseudoregisters. Cue Dave Rivers. It might be be better with LE facilities, but I understand LE has its drawbacks. BTW, are there 64-bit forms of CXD and DXD (regardless that 64-bit address space strains the notion of register)? -- gil -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
On Sun, 21 Feb 2010 18:00:19 -0800 Charles Mills charl...@mcn.org wrote: :I'm writing a fairly large MVS batch application in C++. At several points :it is necessary to call library type routines that I am writing in :assembler. Several of the routines (unfortunately) need to use QSAM macros :and so need below-the-line storage. :Obviously I could do a GETMAIN or STORAGE OBTAIN LOC=24 on the way in and :FREEMAIN or STORAGE RELEASE on the way out. But that's less than optimal for :a routine that is called multiple times. (And it would not work at all if :the routine had to save state across calls, but fortunately that is not the :case, at least for my requirements so far.) :I could make the calling C++ responsible for providing a work area :obtained with _malloc24(). But I don't like that for aesthetic reasons - :violates encapsulation, making the caller responsible for the inner workings :of the called function. :Is there a better way? Is there some sort of anchor word where a library :of called assembler routines could save an address across calls? Is this :what CEECAA_TCASRV_USERWORD in CEECAA is for? Does R12 reliably point to the :CEECAA on entry? Can I count on CEECAA_TCASRV_USERWORD being initialized to :zero? Where is this stuff documented? I don't see much in LE Programming, in :LE ILC, or in the C/C++ Programming Guide. :Is there some LE-supported solution to the whole problem, such as a below :the line stack feature that an individual function (but not the whole :application!) could utilize? You can anchor in name/token. -- Binyamin Dissen bdis...@dissensoftware.com http://www.dissensoftware.com Director, Dissen Software, Bar Grill - Israel Should you use the mailblocks package and expect a response from me, you should preauthorize the dissensoftware.com domain. I very rarely bother responding to challenge/response systems, especially those from irresponsible companies. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
You can anchor in name/token. Considering just functions that require a 24-bit work area and do not need to preserve state across calls, is name/token create and retrieve going to be significantly better performing than FREEMAIN and GETMAIN? (A serious question -- I don't know the answer.) Charles -Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of Binyamin Dissen Sent: Monday, February 22, 2010 12:07 AM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ On Sun, 21 Feb 2010 18:00:19 -0800 Charles Mills charl...@mcn.org wrote: :I'm writing a fairly large MVS batch application in C++. At several points :it is necessary to call library type routines that I am writing in :assembler. Several of the routines (unfortunately) need to use QSAM macros :and so need below-the-line storage. :Obviously I could do a GETMAIN or STORAGE OBTAIN LOC=24 on the way in and :FREEMAIN or STORAGE RELEASE on the way out. But that's less than optimal for :a routine that is called multiple times. (And it would not work at all if :the routine had to save state across calls, but fortunately that is not the :case, at least for my requirements so far.) ... You can anchor in name/token. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
You're right, I think it is safe to assume I am the first and only program **on the TCB**. I kind of ran first on the TCB together with first in the region (and yes, I do know the difference). As I said, I am very familiar with using QSAM in AMODE=31. I know that DCBEs can go above the line. But so long as one byte of storage must reside below the line, one has the problem I described, no matter how much one can also put above the line. Charles -Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of Sam Siegel Sent: Sunday, February 21, 2010 11:13 PM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ On Mon, Feb 22, 2010 at 5:07 AM, Charles Mills charl...@mcn.org wrote: Thanks. Sounds a little risky to assume I am the first/only program in the region -- the jobstep program -- but it's an idea. It is at the TCB level. It is not required to be the jobstep program or TCB. I can understand the reluctance to use this technique if it is deemed not appropriate for your environment based on factors that are not known via the emails. Many financial institutions running 100s of millions of transactions per day use this technique successfully. There are provisions for using QSAM in 31 bit mode. You mean AMODE 31? Yes, I'm real familiar with that. Look up the DCBE in the Macro instructions for datasets. DCB must be in 24 bit storage ... everything else, EODAD, SYNAD, buffers, etc. can be in 31 bit storage. The program that issues the open, get, put, close can be amode 31, rmode 31. Just obtain 24 bit storage for the DCB can copy it below the line. Sam So far as I know DCB must reside in 24-bit storage. So long as one byte must reside BTL I believe I've got the problem I describe. You can assemble the DCB macro into a program that resides above the 16MB line, but the program must move it below the line before using it. All areas that the DCB refers to, such as EXLST and SYNAD, must be below the 16MB line. Charles in.html -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
On Mon, 22 Feb 2010 06:14:16 -0800 Charles Mills charl...@mcn.org wrote: : You can anchor in name/token. :Considering just functions that require a 24-bit work area and do not need :to preserve state across calls, is name/token create and retrieve going to :be significantly better performing than FREEMAIN and GETMAIN? :(A serious question -- I don't know the answer.) The DCB keeps state. :-Original Message- :From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf :Of Binyamin Dissen :Sent: Monday, February 22, 2010 12:07 AM :To: IBM-MAIN@bama.ua.edu :Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ :On Sun, 21 Feb 2010 18:00:19 -0800 Charles Mills charl...@mcn.org wrote: ::I'm writing a fairly large MVS batch application in C++. At several points ::it is necessary to call library type routines that I am writing in ::assembler. Several of the routines (unfortunately) need to use QSAM macros ::and so need below-the-line storage. ::Obviously I could do a GETMAIN or STORAGE OBTAIN LOC=24 on the way in and ::FREEMAIN or STORAGE RELEASE on the way out. But that's less than optimal :for ::a routine that is called multiple times. (And it would not work at all if ::the routine had to save state across calls, but fortunately that is not :the ::case, at least for my requirements so far.) :... :You can anchor in name/token. -- Binyamin Dissen bdis...@dissensoftware.com http://www.dissensoftware.com Director, Dissen Software, Bar Grill - Israel Should you use the mailblocks package and expect a response from me, you should preauthorize the dissensoftware.com domain. I very rarely bother responding to challenge/response systems, especially those from irresponsible companies. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
On Mon, Feb 22, 2010 at 2:19 PM, Charles Mills charl...@mcn.org wrote: You're right, I think it is safe to assume I am the first and only program **on the TCB**. I kind of ran first on the TCB together with first in the region (and yes, I do know the difference). As I said, I am very familiar with using QSAM in AMODE=31. I know that DCBEs can go above the line. But so long as one byte of storage must reside below the line, one has the problem I described, no matter how much one can also put above the line. Charles I misunderstood your comment about AMODE=31. My apologies if my comments appeared as an attack or criticism. That was not my intent. Another possibility is to create an address specific dataspace and hang it off the jstcb's DU-AL. You can save the token via the name token service. I'm pretty sure that the retrieval code associated with name token service is going to be faster than getmain/freemain or storage obtain/release functions. Cheers, Sam -Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of Sam Siegel Sent: Sunday, February 21, 2010 11:13 PM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ On Mon, Feb 22, 2010 at 5:07 AM, Charles Mills charl...@mcn.org wrote: Thanks. Sounds a little risky to assume I am the first/only program in the region -- the jobstep program -- but it's an idea. It is at the TCB level. It is not required to be the jobstep program or TCB. I can understand the reluctance to use this technique if it is deemed not appropriate for your environment based on factors that are not known via the emails. Many financial institutions running 100s of millions of transactions per day use this technique successfully. There are provisions for using QSAM in 31 bit mode. You mean AMODE 31? Yes, I'm real familiar with that. Look up the DCBE in the Macro instructions for datasets. DCB must be in 24 bit storage ... everything else, EODAD, SYNAD, buffers, etc. can be in 31 bit storage. The program that issues the open, get, put, close can be amode 31, rmode 31. Just obtain 24 bit storage for the DCB can copy it below the line. Sam So far as I know DCB must reside in 24-bit storage. So long as one byte must reside BTL I believe I've got the problem I describe. You can assemble the DCB macro into a program that resides above the 16MB line, but the program must move it below the line before using it. All areas that the DCB refers to, such as EXLST and SYNAD, must be below the 16MB line. Charles in.html -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
The DCB keeps state. I know that very well, but that wasn't the question. The question was is name/token create/retrieve better performing than GETMAIN/FREEMAIN (or STORAGE OBTAIN/RELEASE)? There are lots of situations where a function might need QSAM in 24-bit storage but not need to save state (save a DCB) across calls: - a function that opened, read, and closed a dataset and summarized the results in some way for the caller. - a function that copied one dataset to another. - a function that issued RDJFCB, returning the JFCB to the caller (yes, I know there are other ways to get a JFCB) - in the function that is currently on my plate, the DCB is used with ATTACH and is opened and closed within a single call to the function. - there's another one on my plate in which a DCB is opened and closed within a single call, but it's too complicated and distracting to explain the purpose in an e-mail. Charles -Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of Binyamin Dissen Sent: Monday, February 22, 2010 6:24 AM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ On Mon, 22 Feb 2010 06:14:16 -0800 Charles Mills charl...@mcn.org wrote: : You can anchor in name/token. :Considering just functions that require a 24-bit work area and do not need :to preserve state across calls, is name/token create and retrieve going to :be significantly better performing than FREEMAIN and GETMAIN? :(A serious question -- I don't know the answer.) The DCB keeps state. :-Original Message- :From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf :Of Binyamin Dissen :Sent: Monday, February 22, 2010 12:07 AM :To: IBM-MAIN@bama.ua.edu :Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ :On Sun, 21 Feb 2010 18:00:19 -0800 Charles Mills charl...@mcn.org wrote: ::I'm writing a fairly large MVS batch application in C++. At several points ::it is necessary to call library type routines that I am writing in ::assembler. Several of the routines (unfortunately) need to use QSAM macros ::and so need below-the-line storage. ::Obviously I could do a GETMAIN or STORAGE OBTAIN LOC=24 on the way in and ::FREEMAIN or STORAGE RELEASE on the way out. But that's less than optimal :for ::a routine that is called multiple times. (And it would not work at all if ::the routine had to save state across calls, but fortunately that is not :the ::case, at least for my requirements so far.) :... :You can anchor in name/token. -- Binyamin Dissen bdis...@dissensoftware.com http://www.dissensoftware.com Director, Dissen Software, Bar Grill - Israel Should you use the mailblocks package and expect a response from me, you should preauthorize the dissensoftware.com domain. I very rarely bother responding to challenge/response systems, especially those from irresponsible companies. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
Charles, We have been doing C++/assembler mixed development for some time (JZOS, Co:Z), and here are some lessons that we learned: 1) 24-bit storage is a pain (there's not even a malloc24 in the C library that works if you are in AMODE31.) We normally allocate a pointer to 24-bit storage in an instance variable, and free it in a destructor or when not needed any longer Thankfully, there are not too many things than need to be 24 bit any longer. 2) C++ works best when you use XPLINK linkage. If you are running XPLINK, it is very handy to write your assembler routines in XPLINK and then you can allocate the workarea (prefixed by a 18-word SAVEAREA for your assembler routine on the XPLINK stack. This is very fast and easy, and avoids having to GETMAIN/FREEMAIN in your assembler routines for storage that lasts just for that call.Unfortunately, this only works in 31-bit mode, since in 64-bit mode the stack is above the bar. 64-bit mode is a PITA, since very few of the assembler control blocks that you need can live above the bar. It would be really cool if there were a way to have a 31-bit XPLINK stack in LP64... Don't let anyone tell you that z/OS is a real 64-bit OS :-) 3) The C library EDCDSECT tool is really handy for creating a C mapping of your assembler workarea DSECTS. Feel free to contact me offline if you want to discuss more. Kirk Wolf Dovetailed Technologies http://dovetail.com On Sun, Feb 21, 2010 at 8:00 PM, Charles Mills charl...@mcn.org wrote: I'm writing a fairly large MVS batch application in C++. At several points it is necessary to call library type routines that I am writing in assembler. Several of the routines (unfortunately) need to use QSAM macros and so need below-the-line storage. Obviously I could do a GETMAIN or STORAGE OBTAIN LOC=24 on the way in and FREEMAIN or STORAGE RELEASE on the way out. But that's less than optimal for a routine that is called multiple times. (And it would not work at all if the routine had to save state across calls, but fortunately that is not the case, at least for my requirements so far.) I could make the calling C++ responsible for providing a work area obtained with _malloc24(). But I don't like that for aesthetic reasons - violates encapsulation, making the caller responsible for the inner workings of the called function. Is there a better way? Is there some sort of anchor word where a library of called assembler routines could save an address across calls? Is this what CEECAA_TCASRV_USERWORD in CEECAA is for? Does R12 reliably point to the CEECAA on entry? Can I count on CEECAA_TCASRV_USERWORD being initialized to zero? Where is this stuff documented? I don't see much in LE Programming, in LE ILC, or in the C/C++ Programming Guide. Is there some LE-supported solution to the whole problem, such as a below the line stack feature that an individual function (but not the whole application!) could utilize? Thanks, Charles Mills -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
-Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of Charles Mills Sent: Sunday, February 21, 2010 8:00 PM To: IBM-MAIN@bama.ua.edu Subject: Best practice for 24-bit storage in assembler called from C/C++ I'm writing a fairly large MVS batch application in C++. At several points it is necessary to call library type routines that I am writing in assembler. Several of the routines (unfortunately) need to use QSAM macros and so need below-the-line storage. Obviously I could do a GETMAIN or STORAGE OBTAIN LOC=24 on the way in and FREEMAIN or STORAGE RELEASE on the way out. But that's less than optimal for a routine that is called multiple times. (And it would not work at all if the routine had to save state across calls, but fortunately that is not the case, at least for my requirements so far.) I could make the calling C++ responsible for providing a work area obtained with _malloc24(). But I don't like that for aesthetic reasons - violates encapsulation, making the caller responsible for the inner workings of the called function. Is there a better way? Is there some sort of anchor word where a library of called assembler routines could save an address across calls? Is this what CEECAA_TCASRV_USERWORD in CEECAA is for? Does R12 reliably point to the CEECAA on entry? Can I count on CEECAA_TCASRV_USERWORD being initialized to zero? Where is this stuff documented? I don't see much in LE Programming, in LE ILC, or in the C/C++ Programming Guide. SNIP If you KNOW that you will be serialized, then you can either build your DCB info into a REUSE program that you can LOAD. You can then call it to do the I/O that you need done, not get into all the overhead of multiple OPEN/CLOSE, etc. You can then do an INIT call and a Terminate call for the OPEN and CLOSE issues. Otherwise, you can get the storage from your assembler routine, and then have it IDENTIFY that storage so that you can find it again using LOAD, or a run of the CDE chain(s). Just two options you might want to consider. Regards, Steve Thompson -- Opinions expressed by this poster may not reflect those of poster's employer -- -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
IDENTIFY is an interesting idea. I would suspect lower overhead than name/token. But can you IDENTIFY an address in GETMAIN storage? Doesn't it have to be inside a real load module? Charles -Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of Thompson, Steve Sent: Monday, February 22, 2010 7:31 AM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ ... Otherwise, you can get the storage from your assembler routine, and then have it IDENTIFY that storage so that you can find it again using LOAD, or a run of the CDE chain(s). -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
-Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of Charles Mills Sent: Monday, February 22, 2010 10:11 AM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ IDENTIFY is an interesting idea. I would suspect lower overhead than name/token. But can you IDENTIFY an address in GETMAIN storage? Doesn't it have to be inside a real load module? Charles SNIPPAGE Yes, the doc does say that (I just looked at my hard drive copy of the z/OS 1.7 manuals). I remember having done something with IDENTIFY some years ago, and it was to handle some storage that we had done a GETMAIN for. But I just don't remember the particulars. So the REUS guy might be your best bet. Regards, Steve Thompson -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
On Mon, 22 Feb 2010 08:10:55 -0800, Charles Mills wrote: IDENTIFY is an interesting idea. I would suspect lower overhead than name/token. But can you IDENTIFY an address in GETMAIN storage? Doesn't it have to be inside a real load module? Only if you're not authorized. (No good reason.) Or, LOAD a REUS,NORENT,NOREFR CSECT and use that for the anchor. REUS causes subsequent calls to return the samd address. Calls after the first should DELETE it, just to keep the reference count from overflowing. Programmers used to do lots of things such as this before name/token became available. Why do you think IDENTIFY (with LOAD) has lower overhead? -- gil -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
I think we're getting a lot of suggestions as if this were some system service. Name/token, CDE lookups and such are fine if you need to bootstrap yourself from some unknown state. The description of this program is just batch. Save the address in an external variable. LE provides macros to allocate and access externs from assembler. See CEEPDDA and CEEPLDA. Read the LE Programming Guide for descriptions. You can even share these areas with your C++ code. Thompson, Steve wrote: -Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of Charles Mills Sent: Sunday, February 21, 2010 8:00 PM To: IBM-MAIN@bama.ua.edu Subject: Best practice for 24-bit storage in assembler called from C/C++ I'm writing a fairly large MVS batch application in C++. At several points it is necessary to call library type routines that I am writing in assembler. Several of the routines (unfortunately) need to use QSAM macros and so need below-the-line storage. Obviously I could do a GETMAIN or STORAGE OBTAIN LOC=24 on the way in and FREEMAIN or STORAGE RELEASE on the way out. But that's less than optimal for a routine that is called multiple times. (And it would not work at all if the routine had to save state across calls, but fortunately that is not the case, at least for my requirements so far.) I could make the calling C++ responsible for providing a work area obtained with _malloc24(). But I don't like that for aesthetic reasons - violates encapsulation, making the caller responsible for the inner workings of the called function. Is there a better way? Is there some sort of anchor word where a library of called assembler routines could save an address across calls? Is this what CEECAA_TCASRV_USERWORD in CEECAA is for? Does R12 reliably point to the CEECAA on entry? Can I count on CEECAA_TCASRV_USERWORD being initialized to zero? Where is this stuff documented? I don't see much in LE Programming, in LE ILC, or in the C/C++ Programming Guide. SNIP If you KNOW that you will be serialized, then you can either build your DCB info into a REUSE program that you can LOAD. You can then call it to do the I/O that you need done, not get into all the overhead of multiple OPEN/CLOSE, etc. You can then do an INIT call and a Terminate call for the OPEN and CLOSE issues. Otherwise, you can get the storage from your assembler routine, and then have it IDENTIFY that storage so that you can find it again using LOAD, or a run of the CDE chain(s). Just two options you might want to consider. Regards, Steve Thompson -- Opinions expressed by this poster may not reflect those of poster's employer -- -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html -- Don Poitras - zSeries R D - SAS Institute Inc. - SAS Campus Drive mailto:sas...@sas.com (919)531-5637 Fax:677- Cary, NC 27513 -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
Charles Mills wrote: I know that very well, but that wasn't the question. The question was is name/token create/retrieve better performing than GETMAIN/FREEMAIN (or STORAGE OBTAIN/RELEASE)? Name/Token retrieve is quite fast. Name/Token create and delete are far less so. -- Edward E Jaffe Phoenix Software International, Inc 831 Parkview Drive North El Segundo, CA 90245 310-338-0400 x318 edja...@phoenixsoftware.com http://www.phoenixsoftware.com/ -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
Only if you're not authorized. (No good reason.) I really want to run non-authorized because it vastly lowers customer resistance to product trials. Why do you think IDENTIFY (with LOAD) has lower overhead? Just a guess. No good reason. Perhaps it's not. I don't know -- that's why I have been asking here. Charles -Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of Paul Gilmartin Sent: Monday, February 22, 2010 8:28 AM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ On Mon, 22 Feb 2010 08:10:55 -0800, Charles Mills wrote: IDENTIFY is an interesting idea. I would suspect lower overhead than name/token. But can you IDENTIFY an address in GETMAIN storage? Doesn't it have to be inside a real load module? Only if you're not authorized. (No good reason.) Or, LOAD a REUS,NORENT,NOREFR CSECT and use that for the anchor. REUS causes subsequent calls to return the samd address. Calls after the first should DELETE it, just to keep the reference count from overflowing. Programmers used to do lots of things such as this before name/token became available. Why do you think IDENTIFY (with LOAD) has lower overhead? -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
That's the sort of direction I think I am going to go. Thanks, Charles -Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of Don Poitras Sent: Monday, February 22, 2010 8:39 AM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ I think we're getting a lot of suggestions as if this were some system service. Name/token, CDE lookups and such are fine if you need to bootstrap yourself from some unknown state. The description of this program is just batch. Save the address in an external variable. LE provides macros to allocate and access externs from assembler. See CEEPDDA and CEEPLDA. Read the LE Programming Guide for descriptions. You can even share these areas with your C++ code. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
If you are going to keep the DCB open across calls you could: - extend your DCB with the rest of your information, i.e. make the DCB the first part of your control block. - when called, run the DEB queue until you find the one that points back to your DCB which you can identify/verify from the rest of your control block. Date: Mon, 22 Feb 2010 09:04:18 -0800 From: charl...@mcn.org Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ To: IBM-MAIN@bama.ua.edu Only if you're not authorized. (No good reason.) I really want to run non-authorized because it vastly lowers customer resistance to product trials. Why do you think IDENTIFY (with LOAD) has lower overhead? Just a guess. No good reason. Perhaps it's not. I don't know -- that's why I have been asking here. Charles _ Hotmail: Trusted email with powerful SPAM protection. http://clk.atdmt.com/GBL/go/201469227/direct/01/ -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
There is a very old, very terrible technique that I used long ago. I mention it, but do not recommend it. From the currently executing TCB, find the job step TCB (JSTCB). Pick up the TCBFSA pointer from that TCB, which is a pointer to the first save area. Use the word at offset +0 to hold your pointer. -- John McKown Systems Engineer IV IT Administrative Services Group HealthMarkets(r) 9151 Boulevard 26 * N. Richland Hills * TX 76010 (817) 255-3225 phone * (817)-961-6183 cell john.mck...@healthmarkets.com * www.HealthMarkets.com Confidentiality Notice: This e-mail message may contain confidential or proprietary information. If you are not the intended recipient, please contact the sender by reply e-mail and destroy all copies of the original message. HealthMarkets(r) is the brand name for products underwritten and issued by the insurance subsidiaries of HealthMarkets, Inc. -The Chesapeake Life Insurance Company(r), Mid-West National Life Insurance Company of TennesseeSM and The MEGA Life and Health Insurance Company.SM -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
In 003c01cab362$c950c0c0$5bf242...@org, on 02/21/2010 at 06:00 PM, Charles Mills charl...@mcn.org said: Subject: Best practice for 24-bit storage in assembler called from C/C++ Best practice is for new code to be refreshable and reentrant. I'm writing a fairly large MVS batch application in C++. At several points it is necessary to call library type routines that I am writing in assembler. Several of the routines (unfortunately) need to use QSAM macros and so need below-the-line storage. The issues are the same whether the storage is above the line or below. Obviously I could do a GETMAIN or STORAGE OBTAIN LOC=24 on the way in and FREEMAIN or STORAGE RELEASE on the way out. Don't you want to leave the DCB open between calls? I could make the calling C++ responsible for providing a work area obtained with _malloc24(). But I don't like that for aesthetic reasons - violates encapsulation, making the caller responsible for the inner workings of the called function. Not if that storage is a black box. Is there a better way? Does LE use a CXD to allocate a pseudo-register vector? Is there some LE-supported solution to the whole problem, such as a below the line stack feature Unless you're closing the DCB after every call, you want it on the heap rather than the stack. -- Shmuel (Seymour J.) Metz, SysProg and JOAT ISO position; see http://patriot.net/~shmuel/resume/brief.html We don't care. We don't have to care, we're Congress. (S877: The Shut up and Eat Your spam act of 2003) -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
Don't you want to leave the DCB open between calls? No Charles -Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of Shmuel Metz (Seymour J.) Sent: Monday, February 22, 2010 8:35 AM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ In 003c01cab362$c950c0c0$5bf242...@org, on 02/21/2010 at 06:00 PM, Charles Mills charl...@mcn.org said: Subject: Best practice for 24-bit storage in assembler called from C/C++ Best practice is for new code to be refreshable and reentrant. I'm writing a fairly large MVS batch application in C++. At several points it is necessary to call library type routines that I am writing in assembler. Several of the routines (unfortunately) need to use QSAM macros and so need below-the-line storage. The issues are the same whether the storage is above the line or below. Obviously I could do a GETMAIN or STORAGE OBTAIN LOC=24 on the way in and FREEMAIN or STORAGE RELEASE on the way out. Don't you want to leave the DCB open between calls? I could make the calling C++ responsible for providing a work area obtained with _malloc24(). But I don't like that for aesthetic reasons - violates encapsulation, making the caller responsible for the inner workings of the called function. Not if that storage is a black box. Is there a better way? Does LE use a CXD to allocate a pseudo-register vector? Is there some LE-supported solution to the whole problem, such as a below the line stack feature tml -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
On 21 February 2010 21:00, Charles Mills charl...@mcn.org wrote: I'm writing a fairly large MVS batch application in C++. At several points it is necessary to call library type routines that I am writing in assembler. Several of the routines (unfortunately) need to use QSAM macros and so need below-the-line storage. Obviously I could do a GETMAIN or STORAGE OBTAIN LOC=24 on the way in and FREEMAIN or STORAGE RELEASE on the way out. But that's less than optimal for a routine that is called multiple times. (And it would not work at all if the routine had to save state across calls, but fortunately that is not the case, at least for my requirements so far.) It sounds as though you're doing a relatively large amount of processing on each call, i.e. you're not just reading a record and return it. So perhaps GETMAIN on the way in, and FREEMAIN upon exit wouldn't be too bad. I could make the calling C++ responsible for providing a work area obtained with _malloc24(). But I don't like that for aesthetic reasons - violates encapsulation, making the caller responsible for the inner workings of the called function. If your library routines are logically related, you could have an init call that returns a handle to the C++ routine, which would be responsible for maintaining it across calls. Then the handle is part of each subsequent call, including the final cleanup one. That sounds like an appropriate level of opacity/encapsulation. If you want to think of all this in terms of objects and constructors/destructors, well fine. The handle is really just the address of your BTL storage block, of course. Tony H. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
Thanks, Tony. Yes, the amount of processing varies but is more than atomic, I guess. It does not fit a model of open/get/get/get/close for which a handle is well-suited. There's not much relationship among the routines other than that they're all part of a single larger solution, they're all in assembler, and I wrote them all g. I thought I had a pretty good solution and I just spent a frustrating afternoon coding it -- but I've hit a possibly fatal snag. I had this bright idea of coding a pointer in global storage in the C++ code and doing a __malloc24() into it, and then referencing it with EXTRN from the assembler, but the pre-linker is not resolving it. The fundamental problem I guess is that any solution that keeps a pointer around somewhere in the code is fundamentally not reentrant, unless I can figure out how to utilize pseudo-registers. I've heard the term pseudo-register for years but I have never delved into them. Perhaps now is the time. RELATED: is anyone using void *__malloc24(size_t size);? If you code it then it does not compile; if you code your own declaration then it does not link. At least not in my code. Yes, I included stdlib.h. Obviously, not a big deal to write an assembler GETMAIN routine, but still ... Charles -Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of Tony Harminc Sent: Monday, February 22, 2010 5:54 PM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ On 21 February 2010 21:00, Charles Mills charl...@mcn.org wrote: I'm writing a fairly large MVS batch application in C++. At several points it is necessary to call library type routines that I am writing in assembler. Several of the routines (unfortunately) need to use QSAM macros and so need below-the-line storage. Obviously I could do a GETMAIN or STORAGE OBTAIN LOC=24 on the way in and FREEMAIN or STORAGE RELEASE on the way out. But that's less than optimal for a routine that is called multiple times. (And it would not work at all if the routine had to save state across calls, but fortunately that is not the case, at least for my requirements so far.) It sounds as though you're doing a relatively large amount of processing on each call, i.e. you're not just reading a record and return it. So perhaps GETMAIN on the way in, and FREEMAIN upon exit wouldn't be too bad. I could make the calling C++ responsible for providing a work area obtained with _malloc24(). But I don't like that for aesthetic reasons - violates encapsulation, making the caller responsible for the inner workings of the called function. If your library routines are logically related, you could have an init call that returns a handle to the C++ routine, which would be responsible for maintaining it across calls. Then the handle is part of each subsequent call, including the final cleanup one. That sounds like an appropriate level of opacity/encapsulation. If you want to think of all this in terms of objects and constructors/destructors, well fine. The handle is really just the address of your BTL storage block, of course. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
In article 01c601cab431$e5207ff0$af617f...@org you wrote: Thanks, Tony. Yes, the amount of processing varies but is more than atomic, I guess. It does not fit a model of open/get/get/get/close for which a handle is well-suited. There's not much relationship among the routines other than that they're all part of a single larger solution, they're all in assembler, and I wrote them all g. I thought I had a pretty good solution and I just spent a frustrating afternoon coding it -- but I've hit a possibly fatal snag. I had this bright idea of coding a pointer in global storage in the C++ code and doing a __malloc24() into it, and then referencing it with EXTRN from the assembler, but the pre-linker is not resolving it. The fundamental problem I guess is that any solution that keeps a pointer around somewhere in the code is fundamentally not reentrant, unless I can figure out how to utilize pseudo-registers. I've heard the term pseudo-register for years but I have never delved into them. Perhaps now is the time. LE uses the term WSA (Writable Static Area.) It's where reentrant externs and statics live. You get it when you compile your C/C++ program with the RENT option. If you want to use this in assembler, you should use the LE macros rather than trying to use CXD and qcons and such. RELATED: is anyone using void *__malloc24(size_t size);? If you code it then it does not compile; if you code your own declaration then it does not link. At least not in my code. Yes, I included stdlib.h. Obviously, not a big deal to write an assembler GETMAIN routine, but still ... __malloc31 and __malloc24 were intended to be used by LP64 callers. If you really want to use them, I think you'll need to convert your program to 64-bit. If the only use is to hold a DCB, this is overkill. Charles -Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of Tony Harminc Sent: Monday, February 22, 2010 5:54 PM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ On 21 February 2010 21:00, Charles Mills charl...@mcn.org wrote: I'm writing a fairly large MVS batch application in C++. At several points it is necessary to call library type routines that I am writing in assembler. Several of the routines (unfortunately) need to use QSAM macros and so need below-the-line storage. Obviously I could do a GETMAIN or STORAGE OBTAIN LOC=24 on the way in and FREEMAIN or STORAGE RELEASE on the way out. But that's less than optimal for a routine that is called multiple times. (And it would not work at all if the routine had to save state across calls, but fortunately that is not the case, at least for my requirements so far.) It sounds as though you're doing a relatively large amount of processing on each call, i.e. you're not just reading a record and return it. So perhaps GETMAIN on the way in, and FREEMAIN upon exit wouldn't be too bad. I could make the calling C++ responsible for providing a work area obtained with _malloc24(). But I don't like that for aesthetic reasons - violates encapsulation, making the caller responsible for the inner workings of the called function. If your library routines are logically related, you could have an init call that returns a handle to the C++ routine, which would be responsible for maintaining it across calls. Then the handle is part of each subsequent call, including the final cleanup one. That sounds like an appropriate level of opacity/encapsulation. If you want to think of all this in terms of objects and constructors/destructors, well fine. The handle is really just the address of your BTL storage block, of course. -- Don Poitras - SAS Development - SAS Institute Inc. - SAS Campus Drive sas...@sas.com (919) 531-5637Cary, NC 27513 -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
__malloc24 were intended to be used by LP64 callers Does that make any sense? Only a 64 bit user would want below the 16 MB line storage? And did they ever consider documenting this? Charles -Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of Don Poitras Sent: Monday, February 22, 2010 7:37 PM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
Charles Mills wrote: __malloc24 were intended to be used by LP64 callers Does that make any sense? Only a 64 bit user would want below the 16 MB line storage? And did they ever consider documenting this? They did. The C/C++ runtime library reference clearly states LP64. It's obviously a design error because it's a crazy restriction. If Kelly Arrey is watching maybe she can set the wheels in motion to changing it. Otherwise there is an IBM C/C++ forum where you can make your grievances known. Charles -Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of Don Poitras Sent: Monday, February 22, 2010 7:37 PM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
Charles Mills wrote: The fundamental problem I guess is that any solution that keeps a pointer around somewhere in the code is fundamentally not reentrant, unless I can figure out how to utilize pseudo-registers. I've heard the term pseudo-register for years but I have never delved into them. Perhaps now is the time. You're fundamentally not reentrant if you use any kind of global data. That may be name/tokens, control block anchors or WSA. That may not be a problem for you if you only want one instance of the routine. I prefer to design C++ applications to use objects which can handle multiple instantiations of the same class even if I only need one instance. You never know when that requirement may change. RELATED: is anyone using void *__malloc24(size_t size);? If you code it then it does not compile; if you code your own declaration then it does not link. At least not in my code. Yes, I included stdlib.h. Obviously, not a big deal to write an assembler GETMAIN routine, but still ... Charles -Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of Tony Harminc Sent: Monday, February 22, 2010 5:54 PM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ On 21 February 2010 21:00, Charles Mills charl...@mcn.org wrote: I'm writing a fairly large MVS batch application in C++. At several points it is necessary to call library type routines that I am writing in assembler. Several of the routines (unfortunately) need to use QSAM macros and so need below-the-line storage. Obviously I could do a GETMAIN or STORAGE OBTAIN LOC=24 on the way in and FREEMAIN or STORAGE RELEASE on the way out. But that's less than optimal for a routine that is called multiple times. (And it would not work at all if the routine had to save state across calls, but fortunately that is not the case, at least for my requirements so far.) It sounds as though you're doing a relatively large amount of processing on each call, i.e. you're not just reading a record and return it. So perhaps GETMAIN on the way in, and FREEMAIN upon exit wouldn't be too bad. I could make the calling C++ responsible for providing a work area obtained with _malloc24(). But I don't like that for aesthetic reasons - violates encapsulation, making the caller responsible for the inner workings of the called function. If your library routines are logically related, you could have an init call that returns a handle to the C++ routine, which would be responsible for maintaining it across calls. Then the handle is part of each subsequent call, including the final cleanup one. That sounds like an appropriate level of opacity/encapsulation. If you want to think of all this in terms of objects and constructors/destructors, well fine. The handle is really just the address of your BTL storage block, of course. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Best practice for 24-bit storage in assembler called from C/C++
I'm writing a fairly large MVS batch application in C++. At several points it is necessary to call library type routines that I am writing in assembler. Several of the routines (unfortunately) need to use QSAM macros and so need below-the-line storage. Obviously I could do a GETMAIN or STORAGE OBTAIN LOC=24 on the way in and FREEMAIN or STORAGE RELEASE on the way out. But that's less than optimal for a routine that is called multiple times. (And it would not work at all if the routine had to save state across calls, but fortunately that is not the case, at least for my requirements so far.) I could make the calling C++ responsible for providing a work area obtained with _malloc24(). But I don't like that for aesthetic reasons - violates encapsulation, making the caller responsible for the inner workings of the called function. Is there a better way? Is there some sort of anchor word where a library of called assembler routines could save an address across calls? Is this what CEECAA_TCASRV_USERWORD in CEECAA is for? Does R12 reliably point to the CEECAA on entry? Can I count on CEECAA_TCASRV_USERWORD being initialized to zero? Where is this stuff documented? I don't see much in LE Programming, in LE ILC, or in the C/C++ Programming Guide. Is there some LE-supported solution to the whole problem, such as a below the line stack feature that an individual function (but not the whole application!) could utilize? Thanks, Charles Mills -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
I would write the routines with init/term (Constructors/Destructors) functions that allocate and free resources. Have the init return a handle that you pass to the process/term functions, usually just an address of a control block. Think of stdio fopen(), fclose(), fread() etc socket functions etc that use handles. Charles Mills wrote: I'm writing a fairly large MVS batch application in C++. At several points it is necessary to call library type routines that I am writing in assembler. Several of the routines (unfortunately) need to use QSAM macros and so need below-the-line storage. Obviously I could do a GETMAIN or STORAGE OBTAIN LOC=24 on the way in and FREEMAIN or STORAGE RELEASE on the way out. But that's less than optimal for a routine that is called multiple times. (And it would not work at all if the routine had to save state across calls, but fortunately that is not the case, at least for my requirements so far.) I could make the calling C++ responsible for providing a work area obtained with _malloc24(). But I don't like that for aesthetic reasons - violates encapsulation, making the caller responsible for the inner workings of the called function. Is there a better way? Is there some sort of anchor word where a library of called assembler routines could save an address across calls? Is this what CEECAA_TCASRV_USERWORD in CEECAA is for? Does R12 reliably point to the CEECAA on entry? Can I count on CEECAA_TCASRV_USERWORD being initialized to zero? Where is this stuff documented? I don't see much in LE Programming, in LE ILC, or in the C/C++ Programming Guide. Is there some LE-supported solution to the whole problem, such as a below the line stack feature that an individual function (but not the whole application!) could utilize? Thanks, Charles Mills -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
On Mon, Feb 22, 2010 at 2:00 AM, Charles Mills charl...@mcn.org wrote: I'm writing a fairly large MVS batch application in C++. At several points it is necessary to call library type routines that I am writing in assembler. Several of the routines (unfortunately) need to use QSAM macros and so need below-the-line storage. Obviously I could do a GETMAIN or STORAGE OBTAIN LOC=24 on the way in and FREEMAIN or STORAGE RELEASE on the way out. But that's less than optimal for a routine that is called multiple times. (And it would not work at all if the routine had to save state across calls, but fortunately that is not the case, at least for my requirements so far.) I could make the calling C++ responsible for providing a work area obtained with _malloc24(). But I don't like that for aesthetic reasons - violates encapsulation, making the caller responsible for the inner workings of the called function. Is there a better way? Is there some sort of anchor word where a library of called assembler routines could save an address across calls? Is this what CEECAA_TCASRV_USERWORD in CEECAA is for? Does R12 reliably point to the CEECAA on entry? Can I count on CEECAA_TCASRV_USERWORD being initialized to zero? Where is this stuff documented? I don't see much in LE Programming, in LE ILC, or in the C/C++ Programming Guide. TCBFSA points to the first save area. Use word 0 of the save area pointed to by TCBFSA as an anchor for an array of fullwords. Each full word in that array, can be an anchor for memory or other data structures needed by the assembler routines. Init unused values to bin-zero. The assembler programs can find these structures via the TCB without any dependency on LE anchors or other LE machinery. Right after your C/C++ program starts call an assembler routine to initialize the structures just described. This can be done in C/C++ also by create a C/C++ struct of the PSA and setting a pointer to the PSA structure to bin-zero. Once this is done you can obtain addresses and other values just like an assembler program. The only pain is recreating the structures. I typically just fill in the variables that I need and set the rest of the sections to filler. Additionally, this gives you full thread (TCB) Independence for your assembler routines since they get a new set of anchors with each TCB. As a side note, look at the non-vsam access method macros. There are provisions for using QSAM in 31 bit mode. Regards, Sam Is there some LE-supported solution to the whole problem, such as a below the line stack feature that an individual function (but not the whole application!) could utilize? Thanks, Charles Mills -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
Thanks. Sounds a little risky to assume I am the first/only program in the region -- the jobstep program -- but it's an idea. There are provisions for using QSAM in 31 bit mode. You mean AMODE 31? Yes, I'm real familiar with that. So far as I know DCB must reside in 24-bit storage. So long as one byte must reside BTL I believe I've got the problem I describe. You can assemble the DCB macro into a program that resides above the 16MB line, but the program must move it below the line before using it. All areas that the DCB refers to, such as EXLST and SYNAD, must be below the 16MB line. Charles -Original Message- TCBFSA points to the first save area. Use word 0 of the save area pointed to by TCBFSA as an anchor for an array of fullwords. Each full word in that array, can be an anchor for memory or other data structures needed by the assembler routines. Init unused values to bin-zero. The assembler programs can find these structures via the TCB without any dependency on LE anchors or other LE machinery. Right after your C/C++ program starts call an assembler routine to initialize the structures just described. This can be done in C/C++ also by create a C/C++ struct of the PSA and setting a pointer to the PSA structure to bin-zero. Once this is done you can obtain addresses and other values just like an assembler program. The only pain is recreating the structures. I typically just fill in the variables that I need and set the rest of the sections to filler. Additionally, this gives you full thread (TCB) Independence for your assembler routines since they get a new set of anchors with each TCB. As a side note, look at the non-vsam access method macros. There are provisions for using QSAM in 31 bit mode. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
Interesting concept: wrap the assembler routines in a C++ class with an initiator that allocates the storage. All public access to the assembler functions through a C++ method wrapper. So a public C++ method might be int assemblerfunc(int functionalparm1, char *functionalparm2); In turn it would simply call extern OS int ASSEMFUN(void *workarea24, int functionalparm2, char *functionalparm2); Seems like an extra layer of complexity but it does solve the problems I described. Charles -Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of David Crayford Sent: Sunday, February 21, 2010 7:54 PM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ I would write the routines with init/term (Constructors/Destructors) functions that allocate and free resources. Have the init return a handle that you pass to the process/term functions, usually just an address of a control block. Think of stdio fopen(), fclose(), fread() etc socket functions etc that use handles. Charles Mills wrote: I'm writing a fairly large MVS batch application in C++. At several points it is necessary to call library type routines that I am writing in assembler. Several of the routines (unfortunately) need to use QSAM macros and so need below-the-line storage. Obviously I could do a GETMAIN or STORAGE OBTAIN LOC=24 on the way in and FREEMAIN or STORAGE RELEASE on the way out. But that's less than optimal for a routine that is called multiple times. (And it would not work at all if the routine had to save state across calls, but fortunately that is not the case, at least for my requirements so far.) I could make the calling C++ responsible for providing a work area obtained with _malloc24(). But I don't like that for aesthetic reasons - violates encapsulation, making the caller responsible for the inner workings of the called function. Is there a better way? Is there some sort of anchor word where a library of called assembler routines could save an address across calls? Is this what CEECAA_TCASRV_USERWORD in CEECAA is for? Does R12 reliably point to the CEECAA on entry? Can I count on CEECAA_TCASRV_USERWORD being initialized to zero? Where is this stuff documented? I don't see much in LE Programming, in LE ILC, or in the C/C++ Programming Guide. Is there some LE-supported solution to the whole problem, such as a below the line stack feature that an individual function (but not the whole application!) could utilize? Thanks, Charles Mills -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html
Re: Best practice for 24-bit storage in assembler called from C/C++
Charles Mills wrote: Interesting concept: wrap the assembler routines in a C++ class with an initiator that allocates the storage. All public access to the assembler functions through a C++ method wrapper. So a public C++ method might be int assemblerfunc(int functionalparm1, char *functionalparm2); In turn it would simply call extern OS int ASSEMFUN(void *workarea24, int functionalparm2, char *functionalparm2); Exactly. Write you assembler routines to take a function code parameter and have init/term functions which allocate/free resources. Then you wrap your routine in a C++ classes to take advantage of type safety and scoped contructors/destructors to implement the RAII idiom. By using this technique you wont leak resources and should be exception safe. Very simple hacked example example: extern OS { // assembler routine to do QSAM I/O int ASMQSAM( int function, ... ); } // QSAM I/O wrapper class class QSAMFile { public: // constructor QSAMFile( const string fileName ) { // open the file rc = ASMQSAM( FUNC_OPEN, fp, fileName.c_str() ); } // destructor ~QSAMFile() { // close the file rc = ASMQSAM( FUNC_CLOSE, fp ); } int read( char* buffer, size_t length ) { rc = ASMQSAM( FUNC_READ, fp, buffer, length ); } int write( const char* buffer, size_t length ) { rc = ASMQSAM( FUNC_WRITE, fp, buffer, length ); } private: void * fp; // QSAM routine handle }; Seems like an extra layer of complexity but it does solve the problems I described. An extra layer, but not really that much more complex. This is the basic model I've used for years and it works very well. It's also the same model that most GUI/Networking C++ APIs use, but they wrap the legacy C API code instead of assembler. Charles -Original Message- From: IBM Mainframe Discussion List [mailto:ibm-m...@bama.ua.edu] On Behalf Of David Crayford Sent: Sunday, February 21, 2010 7:54 PM To: IBM-MAIN@bama.ua.edu Subject: Re: Best practice for 24-bit storage in assembler called from C/C++ I would write the routines with init/term (Constructors/Destructors) functions that allocate and free resources. Have the init return a handle that you pass to the process/term functions, usually just an address of a control block. Think of stdio fopen(), fclose(), fread() etc socket functions etc that use handles. Charles Mills wrote: I'm writing a fairly large MVS batch application in C++. At several points it is necessary to call library type routines that I am writing in assembler. Several of the routines (unfortunately) need to use QSAM macros and so need below-the-line storage. Obviously I could do a GETMAIN or STORAGE OBTAIN LOC=24 on the way in and FREEMAIN or STORAGE RELEASE on the way out. But that's less than optimal for a routine that is called multiple times. (And it would not work at all if the routine had to save state across calls, but fortunately that is not the case, at least for my requirements so far.) I could make the calling C++ responsible for providing a work area obtained with _malloc24(). But I don't like that for aesthetic reasons - violates encapsulation, making the caller responsible for the inner workings of the called function. Is there a better way? Is there some sort of anchor word where a library of called assembler routines could save an address across calls? Is this what CEECAA_TCASRV_USERWORD in CEECAA is for? Does R12 reliably point to the CEECAA on entry? Can I count on CEECAA_TCASRV_USERWORD being initialized to zero? Where is this stuff documented? I don't see much in LE Programming, in LE ILC, or in the C/C++ Programming Guide. Is there some LE-supported solution to the whole problem, such as a below the line stack feature that an individual function (but not the whole application!) could utilize? Thanks, Charles Mills -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu
Re: Best practice for 24-bit storage in assembler called from C/C++
On Mon, Feb 22, 2010 at 5:07 AM, Charles Mills charl...@mcn.org wrote: Thanks. Sounds a little risky to assume I am the first/only program in the region -- the jobstep program -- but it's an idea. It is at the TCB level. It is not required to be the jobstep program or TCB. I can understand the reluctance to use this technique if it is deemed not appropriate for your environment based on factors that are not known via the emails. Many financial institutions running 100s of millions of transactions per day use this technique successfully. There are provisions for using QSAM in 31 bit mode. You mean AMODE 31? Yes, I'm real familiar with that. Look up the DCBE in the Macro instructions for datasets. DCB must be in 24 bit storage ... everything else, EODAD, SYNAD, buffers, etc. can be in 31 bit storage. The program that issues the open, get, put, close can be amode 31, rmode 31. Just obtain 24 bit storage for the DCB can copy it below the line. Sam So far as I know DCB must reside in 24-bit storage. So long as one byte must reside BTL I believe I've got the problem I describe. You can assemble the DCB macro into a program that resides above the 16MB line, but the program must move it below the line before using it. All areas that the DCB refers to, such as EXLST and SYNAD, must be below the 16MB line. Charles -Original Message- TCBFSA points to the first save area. Use word 0 of the save area pointed to by TCBFSA as an anchor for an array of fullwords. Each full word in that array, can be an anchor for memory or other data structures needed by the assembler routines. Init unused values to bin-zero. The assembler programs can find these structures via the TCB without any dependency on LE anchors or other LE machinery. Right after your C/C++ program starts call an assembler routine to initialize the structures just described. This can be done in C/C++ also by create a C/C++ struct of the PSA and setting a pointer to the PSA structure to bin-zero. Once this is done you can obtain addresses and other values just like an assembler program. The only pain is recreating the structures. I typically just fill in the variables that I need and set the rest of the sections to filler. Additionally, this gives you full thread (TCB) Independence for your assembler routines since they get a new set of anchors with each TCB. As a side note, look at the non-vsam access method macros. There are provisions for using QSAM in 31 bit mode. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@bama.ua.edu with the message: GET IBM-MAIN INFO Search the archives at http://bama.ua.edu/archives/ibm-main.html