diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c9a23b07..1715d0120 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Zowe Common C Changelog +## `3.0.0` +- Add support for LE 64-bit in isgenq.c (#422). ## `2.17.0` - Fixed `xplatform.loadFileUTF8` when trying to open nonexistent file (#454) diff --git a/c/isgenq.c b/c/isgenq.c index 00bcc08f7..6d65b0198 100644 --- a/c/isgenq.c +++ b/c/isgenq.c @@ -22,14 +22,6 @@ #include "zowetypes.h" #include "isgenq.h" -#if !defined(METTLE) && defined(_LP64) -/* TODO the ISGENQ code may not work under LE 64-bit */ -#error LE 64-bit is not supported -#endif - -#ifdef METTLE -__asm("GLBENQPL ISGENQ MF=(L,GLBENQPL)" : "DS"(GLBENQPL)); -#endif int isgenqTryExclusiveLock(const QName *qname, const RName *rname, @@ -37,15 +29,7 @@ int isgenqTryExclusiveLock(const QName *qname, ENQToken *token, int *reasonCode) { - QName localQName = *qname; - RName localRName = *rname; - -#ifdef METTLE - __asm(" ISGENQ MF=L" : "DS"(isgenqParmList)); - isgenqParmList = GLBENQPL; -#else - char isgenqParmList[512]; -#endif + char parmList[200] = {0}; int rc = 0, rsn = 0; __asm( @@ -59,32 +43,39 @@ int isgenqTryExclusiveLock(const QName *qname, ",CONTENTIONACT=FAIL" ",USERDATA=NO_USERDATA" ",RESLIST=NO" - ",QNAME=(%2)" - ",RNAME=(%3)" - ",RNAMELEN=(%4)" + ",QNAME=%[qname]" + ",RNAME=%[rname]" + ",RNAMELEN=%[rname_len]" ",CONTROL=EXCLUSIVE" ",RESERVEVOLUME=NO" ",SCOPE=VALUE" - ",SCOPEVAL=(%5)" + ",SCOPEVAL=(%[scope])" ",RNL=YES" - ",ENQTOKEN=(%6)" + ",ENQTOKEN=%[token]" ",COND=YES" - ",RETCODE=%0" - ",RSNCODE=%1" - ",PLISTVER=IMPLIED_VERSION" - ",MF=(E,(%7),COMPLETE)" + ",RETCODE=GPR15" + ",RSNCODE=GPR00" + ",PLISTVER=2" + ",MF=(E,%[parmlist],COMPLETE)" " \n" " DROP \n" " POP USING \n" - : "=m"(rc), "=m"(rsn) - : "r"(&localQName.value), "r"(&localRName.value), "r"(&localRName.length), - "r"(&scope), "r"(token), "r"(&isgenqParmList) - : "r0", "r1", "r2", "r14", "r15" + + : [token]"=m"(*token), [rc]"=NR:r15"(rc), [rsn]"=NR:r0"(rsn) + + : [qname]"m"(qname->value), + [rname]"m"(rname->value), + [rname_len]"m"(rname->length), + [scope]"r"(&scope), + [parmlist]"m"(parmList) + + : "r1", "r2", "r14" ); if (reasonCode != NULL) { *reasonCode = rsn; } + return rc; } @@ -94,15 +85,7 @@ int isgenqGetExclusiveLock(const QName *qname, ENQToken *token, int *reasonCode) { - QName localQName = *qname; - RName localRName = *rname; - -#ifdef METTLE - __asm(" ISGENQ MF=L" : "DS"(isgenqParmList)); - isgenqParmList = GLBENQPL; -#else - char isgenqParmList[512]; -#endif + char parmList[200] = {0}; int rc = 0, rsn = 0; __asm( @@ -116,32 +99,39 @@ int isgenqGetExclusiveLock(const QName *qname, ",CONTENTIONACT=WAIT" ",USERDATA=NO_USERDATA" ",RESLIST=NO" - ",QNAME=(%2)" - ",RNAME=(%3)" - ",RNAMELEN=(%4)" + ",QNAME=%[qname]" + ",RNAME=%[rname]" + ",RNAMELEN=%[rname_len]" ",CONTROL=EXCLUSIVE" ",RESERVEVOLUME=NO" ",SCOPE=VALUE" - ",SCOPEVAL=(%5)" + ",SCOPEVAL=(%[scope])" ",RNL=YES" - ",ENQTOKEN=(%6)" + ",ENQTOKEN=%[token]" ",COND=YES" - ",RETCODE=%0" - ",RSNCODE=%1" - ",PLISTVER=IMPLIED_VERSION" - ",MF=(E,(%7),COMPLETE)" + ",RETCODE=GPR15" + ",RSNCODE=GPR00" + ",PLISTVER=2" + ",MF=(E,%[parmlist],COMPLETE)" " \n" " DROP \n" " POP USING \n" - : "=m"(rc), "=m"(rsn) - : "r"(&localQName.value), "r"(&localRName.value), "r"(&localRName.length), - "r"(&scope), "r"(token), "r"(&isgenqParmList) - : "r0", "r1", "r2", "r14", "r15" + + : [token]"=m"(*token), [rc]"=NR:r15"(rc), [rsn]"=NR:r0"(rsn) + + : [qname]"m"(qname->value), + [rname]"m"(rname->value), + [rname_len]"m"(rname->length), + [scope]"r"(&scope), + [parmlist]"m"(parmList) + + : "r1", "r2", "r14" ); if (reasonCode != NULL) { *reasonCode = rsn; } + return rc; } @@ -151,15 +141,7 @@ int isgenqTrySharedLock(const QName *qname, ENQToken *token, int *reasonCode) { - QName localQName = *qname; - RName localRName = *rname; - -#ifdef METTLE - __asm(" ISGENQ MF=L" : "DS"(isgenqParmList)); - isgenqParmList = GLBENQPL; -#else - char isgenqParmList[512]; -#endif + char parmList[200] = {0}; int rc = 0, rsn = 0; __asm( @@ -173,32 +155,39 @@ int isgenqTrySharedLock(const QName *qname, ",CONTENTIONACT=FAIL" ",USERDATA=NO_USERDATA" ",RESLIST=NO" - ",QNAME=(%2)" - ",RNAME=(%3)" - ",RNAMELEN=(%4)" + ",QNAME=%[qname]" + ",RNAME=%[rname]" + ",RNAMELEN=%[rname_len]" ",CONTROL=SHARED" ",RESERVEVOLUME=NO" ",SCOPE=VALUE" - ",SCOPEVAL=(%5)" + ",SCOPEVAL=(%[scope])" ",RNL=YES" - ",ENQTOKEN=(%6)" + ",ENQTOKEN=%[token]" ",COND=YES" - ",RETCODE=%0" - ",RSNCODE=%1" - ",PLISTVER=IMPLIED_VERSION" - ",MF=(E,(%7),COMPLETE)" + ",RETCODE=GPR15" + ",RSNCODE=GPR00" + ",PLISTVER=2" + ",MF=(E,%[parmlist],COMPLETE)" " \n" " DROP \n" " POP USING \n" - : "=m"(rc), "=m"(rsn) - : "r"(&localQName.value), "r"(&localRName.value), "r"(&localRName.length), - "r"(&scope), "r"(token), "r"(&isgenqParmList) - : "r0", "r1", "r2", "r14", "r15" + + : [token]"=m"(*token), [rc]"=NR:r15"(rc), [rsn]"=NR:r0"(rsn) + + : [qname]"m"(qname->value), + [rname]"m"(rname->value), + [rname_len]"m"(rname->length), + [scope]"r"(&scope), + [parmlist]"m"(parmList) + + : "r1", "r2", "r14" ); if (reasonCode != NULL) { *reasonCode = rsn; } + return rc; } @@ -208,15 +197,7 @@ int isgenqGetSharedLock(const QName *qname, ENQToken *token, int *reasonCode) { - QName localQName = *qname; - RName localRName = *rname; - -#ifdef METTLE - __asm(" ISGENQ MF=L" : "DS"(isgenqParmList)); - isgenqParmList = GLBENQPL; -#else - char isgenqParmList[512]; -#endif + char parmList[200] = {0}; int rc = 0, rsn = 0; __asm( @@ -230,32 +211,39 @@ int isgenqGetSharedLock(const QName *qname, ",CONTENTIONACT=WAIT" ",USERDATA=NO_USERDATA" ",RESLIST=NO" - ",QNAME=(%2)" - ",RNAME=(%3)" - ",RNAMELEN=(%4)" + ",QNAME=%[qname]" + ",RNAME=%[rname]" + ",RNAMELEN=%[rname_len]" ",CONTROL=SHARED" ",RESERVEVOLUME=NO" ",SCOPE=VALUE" - ",SCOPEVAL=(%5)" + ",SCOPEVAL=(%[scope])" ",RNL=YES" - ",ENQTOKEN=(%6)" + ",ENQTOKEN=%[token]" ",COND=YES" - ",RETCODE=%0" - ",RSNCODE=%1" - ",PLISTVER=IMPLIED_VERSION" - ",MF=(E,(%7),COMPLETE)" + ",RETCODE=GPR15" + ",RSNCODE=GPR00" + ",PLISTVER=2" + ",MF=(E,%[parmlist],COMPLETE)" " \n" " DROP \n" " POP USING \n" - : "=m"(rc), "=m"(rsn) - : "r"(&localQName.value), "r"(&localRName.value), "r"(&localRName.length), - "r"(&scope), "r"(token), "r"(&isgenqParmList) - : "r0", "r1", "r2", "r14", "r15" + + : [token]"=m"(*token), [rc]"=NR:r15"(rc), [rsn]"=NR:r0"(rsn) + + : [qname]"m"(qname->value), + [rname]"m"(rname->value), + [rname_len]"m"(rname->length), + [scope]"r"(&scope), + [parmlist]"m"(parmList) + + : "r1", "r2", "r14" ); if (reasonCode != NULL) { *reasonCode = rsn; } + return rc; } @@ -264,17 +252,8 @@ int isgenqTestLock(const QName *qname, uint8_t scope, int *reasonCode) { - QName localQName = *qname; - RName localRName = *rname; - -#ifdef METTLE - __asm(" ISGENQ MF=L" : "DS"(isgenqParmList)); - isgenqParmList = GLBENQPL; -#else - char isgenqParmList[512]; -#endif - - ENQToken localToken; + ENQToken token = {0}; + char parmList[200] = {0}; int rc = 0, rsn = 0; __asm( @@ -286,32 +265,39 @@ int isgenqTestLock(const QName *qname, " ISGENQ REQUEST=OBTAIN" ",TEST=YES" ",RESLIST=NO" - ",QNAME=(%2)" - ",RNAME=(%3)" - ",RNAMELEN=(%4)" + ",QNAME=%[qname]" + ",RNAME=%[rname]" + ",RNAMELEN=%[rname_len]" ",CONTROL=EXCLUSIVE" ",RESERVEVOLUME=NO" ",SCOPE=VALUE" - ",SCOPEVAL=(%5)" + ",SCOPEVAL=(%[scope])" ",RNL=YES" - ",ENQTOKEN=(%6)" + ",ENQTOKEN=%[token]" ",COND=YES" - ",RETCODE=%0" - ",RSNCODE=%1" - ",PLISTVER=IMPLIED_VERSION" - ",MF=(E,(%7),COMPLETE)" + ",RETCODE=GPR15" + ",RSNCODE=GPR00" + ",PLISTVER=2" + ",MF=(E,%[parmlist],COMPLETE)" " \n" " DROP \n" " POP USING \n" - : "=m"(rc), "=m"(rsn) - : "r"(&localQName.value), "r"(&localRName.value), "r"(&localRName.length), - "r"(&scope), "r"(&localToken), "r"(&isgenqParmList) - : "r0", "r1", "r2", "r14", "r15" + + : [token]"=m"(token), [rc]"=NR:r15"(rc), [rsn]"=NR:r0"(rsn) + + : [qname]"m"(qname->value), + [rname]"m"(rname->value), + [rname_len]"m"(rname->length), + [scope]"r"(&scope), + [parmlist]"m"(parmList) + + : "r1", "r2", "r14" ); if (reasonCode != NULL) { *reasonCode = rsn; } + return rc; } @@ -329,17 +315,8 @@ int isgenqTestSharedLock(const QName *qname, uint8_t scope, int *reasonCode) { - QName localQName = *qname; - RName localRName = *rname; - -#ifdef METTLE - __asm(" ISGENQ MF=L" : "DS"(isgenqParmList)); - isgenqParmList = GLBENQPL; -#else - char isgenqParmList[512]; -#endif - - ENQToken localToken; + ENQToken token = {0}; + char parmList[200] = {0}; int rc = 0, rsn = 0; __asm( @@ -351,43 +328,45 @@ int isgenqTestSharedLock(const QName *qname, " ISGENQ REQUEST=OBTAIN" ",TEST=YES" ",RESLIST=NO" - ",QNAME=(%2)" - ",RNAME=(%3)" - ",RNAMELEN=(%4)" + ",QNAME=%[qname]" + ",RNAME=%[rname]" + ",RNAMELEN=%[rname_len]" ",CONTROL=SHARED" ",RESERVEVOLUME=NO" ",SCOPE=VALUE" - ",SCOPEVAL=(%5)" + ",SCOPEVAL=(%[scope])" ",RNL=YES" - ",ENQTOKEN=(%6)" + ",ENQTOKEN=%[token]" ",COND=YES" - ",RETCODE=%0" - ",RSNCODE=%1" - ",PLISTVER=IMPLIED_VERSION" - ",MF=(E,(%7),COMPLETE)" + ",RETCODE=GPR15" + ",RSNCODE=GPR00" + ",PLISTVER=2" + ",MF=(E,%[parmlist],COMPLETE)" " \n" " DROP \n" " POP USING \n" - : "=m"(rc), "=m"(rsn) - : "r"(&localQName.value), "r"(&localRName.value), "r"(&localRName.length), - "r"(&scope), "r"(&localToken), "r"(&isgenqParmList) - : "r0", "r1", "r2", "r14", "r15" + + : [token]"=m"(token), [rc]"=NR:r15"(rc), [rsn]"=NR:r0"(rsn) + + : [qname]"m"(qname->value), + [rname]"m"(rname->value), + [rname_len]"m"(rname->length), + [scope]"r"(&scope), + [parmlist]"m"(parmList) + + : "r1", "r2", "r14" ); if (reasonCode != NULL) { *reasonCode = rsn; } + return rc; } -int isgenqReleaseLock(ENQToken *token, int *reasonCode) { +int isgenqReleaseLock(const ENQToken *token, int *reasonCode) { -#ifdef METTLE - __asm(" ISGENQ MF=L" : "DS"(isgenqParmList)); - isgenqParmList = GLBENQPL; -#else - char isgenqParmList[512]; -#endif + char parmList[200] = {0}; int rc = 0, rsn = 0; __asm( @@ -398,24 +377,28 @@ int isgenqReleaseLock(ENQToken *token, int *reasonCode) { " USING ENQREL,2 \n" " ISGENQ REQUEST=RELEASE" ",RESLIST=NO" - ",ENQTOKEN=(%2)" + ",ENQTOKEN=%[token]" ",OWNINGTTOKEN=CURRENT_TASK" ",COND=YES" - ",RETCODE=%0" - ",RSNCODE=%1" - ",PLISTVER=IMPLIED_VERSION" - ",MF=(E,(%3),COMPLETE)" + ",RETCODE=GPR15" + ",RSNCODE=GPR00" + ",PLISTVER=2" + ",MF=(E,%[parmlist],COMPLETE)" " \n" " DROP \n" " POP USING \n" - : "=m"(rc), "=m"(rsn) - : "r"(token), "r"(&isgenqParmList) - : "r0", "r1", "r2", "r14", "r15" + + : [rc]"=NR:r15"(rc), [rsn]"=NR:r0"(rsn) + + : [token]"m"(*token), [parmlist]"m"(parmList) + + : "r1", "r2", "r14" ); if (reasonCode != NULL) { *reasonCode = rsn; } + return rc; } diff --git a/h/isgenq.h b/h/isgenq.h index 753f7ecbb..9f969e8a4 100644 --- a/h/isgenq.h +++ b/h/isgenq.h @@ -53,11 +53,11 @@ typedef struct ENQToken_tag { * being held for this QNAME and RNAME combination. See more details in the * ISGENQ documentation. * - * @param qname Enqueue major name - * @param rname Enqueue minor name - * @param scope Scope of the enqueue (use one of ISGENQ_SCOPE_xxxx) - * @param token Token used to release the enqueue - * @param reasonCode Reason code from ISGENQ + * @param[in] qname Enqueue major name + * @param[in] rname Enqueue minor name + * @param[in] scope Scope of the enqueue (use one of ISGENQ_SCOPE_xxxx) + * @param[out] token Token used to release the enqueue + * @param[out] reasonCode Reason code from ISGENQ * @return Return code from ISGENQ */ int isgenqTryExclusiveLock(const QName *qname, @@ -82,11 +82,11 @@ int isgenqGetExclusiveLockOrFail(const QName *qname, * held for this QNAME and RNAME combination, the current task is suspended. * See more details in the ISGENQ documentation. * - * @param qname Enqueue major name - * @param rname Enqueue minor name - * @param scope Scope of the enqueue (use one of ISGENQ_SCOPE_xxxx) - * @param token Token used to release the enqueue - * @param reasonCode Reason code from ISGENQ + * @param[in] qname Enqueue major name + * @param[in] rname Enqueue minor name + * @param[in] scope Scope of the enqueue (use one of ISGENQ_SCOPE_xxxx) + * @param[out] token Token used to release the enqueue + * @param[out] reasonCode Reason code from ISGENQ * @return Return code from ISGENQ */ int isgenqGetExclusiveLock(const QName *qname, @@ -99,11 +99,11 @@ int isgenqGetExclusiveLock(const QName *qname, * being held for this QNAME and RNAME combination. See more details in the * ISGENQ documentation. * - * @param qname Enqueue major name - * @param rname Enqueue minor name - * @param scope Scope of the enqueue (use one of ISGENQ_SCOPE_xxxx) - * @param token Token used to release the enqueue - * @param reasonCode Reason code from ISGENQ + * @param[in] qname Enqueue major name + * @param[in] rname Enqueue minor name + * @param[in] scope Scope of the enqueue (use one of ISGENQ_SCOPE_xxxx) + * @param[out] token Token used to release the enqueue + * @param[out] reasonCode Reason code from ISGENQ * @return Return code from ISGENQ */ int isgenqTrySharedLock(const QName *qname, @@ -116,11 +116,11 @@ int isgenqTrySharedLock(const QName *qname, * being held for this QNAME and RNAME combination, the current task is * suspended. See more details in the ISGENQ documentation. * - * @param qname Enqueue major name - * @param rname Enqueue minor name - * @param scope Scope of the enqueue (use one of ISGENQ_SCOPE_xxxx) - * @param token Token used to release the enqueue - * @param reasonCode Reason code from ISGENQ + * @param[in] qname Enqueue major name + * @param[in] rname Enqueue minor name + * @param[in] scope Scope of the enqueue (use one of ISGENQ_SCOPE_xxxx) + * @param[out] token Token used to release the enqueue + * @param[out] reasonCode Reason code from ISGENQ * @return Return code from ISGENQ */ int isgenqGetSharedLock(const QName *qname, @@ -134,11 +134,10 @@ int isgenqGetSharedLock(const QName *qname, * acquiring the actual lock in case of success. See more details in the ISGENQ * documentation. * - * @param qname Enqueue major name - * @param rname Enqueue minor name - * @param scope Scope of the enqueue (use one of ISGENQ_SCOPE_xxxx) - * @param token Token used to release the enqueue - * @param reasonCode Reason code from ISGENQ + * @param[in] qname Enqueue major name + * @param[in] rname Enqueue minor name + * @param[in] scope Scope of the enqueue (use one of ISGENQ_SCOPE_xxxx) + * @param[out] reasonCode Reason code from ISGENQ * @return Return code from ISGENQ */ int isgenqTestExclusiveLock(const QName *qname, @@ -150,11 +149,10 @@ int isgenqTestExclusiveLock(const QName *qname, * acquiring the actual lock in case of success. See more details in the ISGENQ * documentation. * - * @param qname Enqueue major name - * @param rname Enqueue minor name - * @param scope Scope of the enqueue (use one of ISGENQ_SCOPE_xxxx) - * @param token Token used to release the enqueue - * @param reasonCode Reason code from ISGENQ + * @param[in] qname Enqueue major name + * @param[in] rname Enqueue minor name + * @param[in] scope Scope of the enqueue (use one of ISGENQ_SCOPE_xxxx) + * @param[out] reasonCode Reason code from ISGENQ * @return Return code from ISGENQ */ int isgenqTestSharedLock(const QName *qname, @@ -166,10 +164,10 @@ int isgenqTestSharedLock(const QName *qname, * @brief The function does the same as isgenqTestExclusiveLock. See more * details in the ISGENQ documentation. * - * @param qname Enqueue major name - * @param rname Enqueue minor name - * @param scope Scope of the enqueue (use one of ISGENQ_SCOPE_xxxx) - * @param reasonCode Reason code from ISGENQ + * @param[in] qname Enqueue major name + * @param[in] rname Enqueue minor name + * @param[in] scope Scope of the enqueue (use one of ISGENQ_SCOPE_xxxx) + * @param[out] reasonCode Reason code from ISGENQ * @return Return code from ISGENQ */ int isgenqTestLock(const QName *qname, @@ -180,11 +178,11 @@ int isgenqTestLock(const QName *qname, * @brief The function releases a lock using the token obtain during the * corresponding get call. See more details in the ISGENQ documentation. * - * @param token Token used to acquire the lock - * @param reasonCode Reason code from ISGENQ + * @param[in] token Token used to acquire the lock + * @param[out] reasonCode Reason code from ISGENQ * @return Return code from ISGENQ */ -int isgenqReleaseLock(ENQToken *token, int *reasonCode); +int isgenqReleaseLock(const ENQToken *token, int *reasonCode); #define IS_ISGENQ_LOCK_OBTAINED($isgenqRC, $isgenqRSN) \ ($isgenqRC <= 4 && ((unsigned)$isgenqRSN & 0xFFFF) != 0x0404) diff --git a/tests/isgenqtest.c b/tests/isgenqtest.c new file mode 100644 index 000000000..864255586 --- /dev/null +++ b/tests/isgenqtest.c @@ -0,0 +1,172 @@ +#ifdef METTLE +#include +#include +#include +#include +#include +#include +#include "metalio.h" +#else +#include "ctype.h" +#include "stddef.h" +#include "stdlib.h" +#include "stdio.h" +#include "string.h" +#endif + +/* + +Metal 64-bit: + +xlc -S -M -qmetal -DSUBPOOL=132 -DMETTLE=1 -DMSGPREFIX='"ZWE"' \ + -qreserved_reg=r12 -Wc,"arch(8),roconst,longname,lp64" -I ../h -\ + ../c/alloc.c \ + ../c/isgenq.c \ + ../c/qsam.c \ + ../c/metalio.c \ + ../c/timeutls.c \ + ../c/utils.c \ + ../c/zos.c \ + isgenqtest.c && \ +as -mgoff -mobject -mflag=nocont --TERM --RENT -o alloc.o alloc.s && \ +as -mgoff -mobject -mflag=nocont --TERM --RENT -o isgenq.o isgenq.s && \ +as -mgoff -mobject -mflag=nocont --TERM --RENT -o qsam.o qsam.s && \ +as -mgoff -mobject -mflag=nocont --TERM --RENT -o metalio.o metalio.s && \ +as -mgoff -mobject -mflag=nocont --TERM --RENT -o timeutls.o timeutls.s && \ +as -mgoff -mobject -mflag=nocont --TERM --RENT -o utils.o utils.s && \ +as -mgoff -mobject -mflag=nocont --TERM --RENT -o zos.o zos.s && \ +as -mgoff -mobject -mflag=nocont --TERM --RENT -o isgenqtest.o isgenqtest.s && \ +_LD_SYSLIB="//'SYS1.CSSLIB'" ld -V -b rent -b case=mixed -b map -b xref \ + -b reus -e main -o "//'$USER.LOADLIB(ISGENQTS)'" \ + alloc.o isgenq.o qsam.o metalio.o timeutls.o utils.o zos.o isgenqtest.o \ + > isgenqtest.lnk + +LE 64-bit: + +xlc "-Wc,LANGLVL(EXTC99),LP64,ASM,ASMLIB('SYS1.MACLIB'),ASMLIB('CEE.SCEEMAC')" \ +-I ../h -o isgenqtest isgenqtest.c ../c/isgenq.c + +*/ + +#include "zowetypes.h" +#include "isgenq.h" + +#ifdef METTLE +static void sleep(int seconds) { + int waitValue = seconds * 100; + __asm( + ASM_PREFIX + " STIMER WAIT,BINTVL=%[interval] \n" + : + : [interval]"m"(waitValue) + : "r0", "r1", "r14", "r15" + ); +} +#else +#include +#endif + + +#define FIELD_SIZE(str, field) sizeof(((str *)0)->field) + +static bool lockTimeValid(const char *value) { + size_t valueLength = strlen(value); + if (valueLength == 0 || valueLength > 4) { + return false; + } + for (size_t i = 0; i < valueLength; i++) { + if (!isdigit(value[i])) { + return false; + } + } + return true; +} + +int main(int argc, char **argv) { + +#ifndef METTLE + + if (argc < 5) { + printf("error: bad parms, use > isgenqtest }\n"); + return 8; + } + + const char *qnameStr = argv[1]; + size_t qnameLength = strlen(qnameStr); + if (qnameLength > FIELD_SIZE(QName, value)) { + printf("error: qname is too long\n"); + return 8; + } + + const char *rnameStr = argv[2]; + size_t rnameLength = strlen(rnameStr); + if (rnameLength > FIELD_SIZE(RName, value)) { + printf("error: rname is too long\n"); + return 8; + } + + char mode = argv[3][0]; + if (mode != 'x' && mode != 's') { + printf("error: bad parms, use {x, s}\n"); + return 8; + } + + const char *lockTimeStr = argv[4]; + if (!lockTimeValid(lockTimeStr)) { + printf("error: bad lock time \'%s\'\n", lockTimeStr); + return 8; + } + int lockTime = atoi(lockTimeStr); + + QName qname = {.value = " "}; + RName rname; + memcpy(qname.value, qnameStr, qnameLength); + memcpy(rname.value, rnameStr, rnameLength); + rname.length = rnameLength; + +#else + + QName qname = {.value = "ZWE "}; + RName rname = {.value = "ISGENQTEST", .length = strlen(rname.value)}; + char mode = 'x'; + int lockTime = 10; + +#endif + + ENQToken token; + + int rc = 0, rsn = 0; + + if (mode == 'x') { + + rc = isgenqTestExclusiveLock(&qname, &rname, ISGENQ_SCOPE_SYSTEM, &rsn); + printf("exclusive test rc = %d, rsn = %08X\n", rc, rsn); + + rc = isgenqTryExclusiveLock(&qname, &rname, ISGENQ_SCOPE_SYSTEM, &token, &rsn); + printf("exclusive lock or fail rc = %d, rsn = %08X\n", rc, rsn); + + rc = isgenqGetExclusiveLock(&qname, &rname, ISGENQ_SCOPE_SYSTEM, &token, &rsn); + printf("exclusive lock rc = %d, rsn = %08X\n", rc, rsn); + + sleep(lockTime); + + } else { + + rc = isgenqTestSharedLock(&qname, &rname, ISGENQ_SCOPE_SYSTEM, &rsn); + printf("shared test rc = %d, rsn = %08X\n", rc, rsn); + + rc = isgenqTrySharedLock(&qname, &rname, ISGENQ_SCOPE_SYSTEM, &token, &rsn); + printf("shared lock or fail rc = %d, rsn = %08X\n", rc, rsn); + + rc = isgenqGetSharedLock(&qname, &rname, ISGENQ_SCOPE_SYSTEM, &token, &rsn); + printf("shared lock rc = %d, rsn = %08X\n", rc, rsn); + + sleep(lockTime); + + } + + rc = isgenqReleaseLock(&token, &rsn); + printf("release rc = %d, rsn = %08X\n", rc, rsn); + + return 0; +}