diff --git a/lockperf.c b/lockperf.c new file mode 100644 index 0000000000000000000000000000000000000000..a2e2a2f6449a38a642b11bfb67f8dc93e38b1c33_bG9ja3BlcmYuYw== --- /dev/null +++ b/lockperf.c @@ -0,0 +1,252 @@ +#ifndef __NEW_STARLET +# define __NEW_STARLET +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <gen64def.h> +#include <starlet.h> +#include <lib$routines.h> +#include <descrip.h> +#include <lckdef.h> +#include <lksbdef.h> +#include <ssdef.h> +#include <stsdef.h> + + +typedef struct { + int _lockCount; + int _elapsed[2]; + unsigned int _cpu; +} Stat_s; + +static enum _ts {KDuration = 0, KLockCount = 1} TypeStop; +static int Pass; +static int Interval; +static int TotLock; +static EndPass; +static int PassDuration; +static int LockCount; +Stat_s StatInfo[8]; /* 8 pass */ + +static $DESCRIPTOR(ParResNameD, "TSTLOCK_PAR"); +static $DESCRIPTOR(SonResNameD, "TSTLOCK_SON"); +static struct _lksb LksbPar; +static struct _lksb LksbSon; + +static void SonLockCompletionAST(int); +static void ParLockCompletionAST(int); + + +static int YesOrNo(const char* str) { + int rep = 2; + while((rep != 0) && (rep != 1)) { + printf("%s", str); + scanf("%d", &rep); + } + return rep; +} + +static void InteractiveQueries() { + int i; + + printf("\nPass (8 max): "); + scanf("%d", &Pass); + + printf("\nStop on (0 : Duration, 1 : locks Count): "); + scanf("%d", &i); + TypeStop = (enum _ts)i; + switch (TypeStop) { + case KDuration: + printf("\nPass Duration: "); + scanf("%d", &PassDuration); + break; + case KLockCount: + printf("\nTotal locks count: "); + scanf("%d", &TotLock); + break; + default: + fprintf(stderr, "\nInvalid stop switch\n"); + exit(SS$_ABORT); + } +} + + +static void SonDoLock(int i) { + int s; + + switch (TypeStop) { + case KDuration: + break; + case KLockCount: + if (TotLock == 0) EndPass = 1; + else --TotLock; + break; + default: + fprintf(stderr, "\nInvalid stop switch\n"); + exit(SS$_ABORT); + } + + s = sys$deq(LksbSon.lksb$l_lkid, 0, 0, 0); + if (! $VMS_STATUS_SUCCESS(s)) exit(s); + + if (!EndPass) { + s = sys$enq(0, LCK$K_EXMODE, &LksbSon, 0, &SonResNameD, + LksbPar.lksb$l_lkid, &SonLockCompletionAST, 0, 0, 0, 0, 0, 0); + if (! $VMS_STATUS_SUCCESS(s)) exit(s); + ++LockCount; + } +} + +static void SonLockCompletionAST(int i) { + SonDoLock(i); +} + +static void ParDoLock(int i) { + int s; + + switch (TypeStop) { + case KDuration: + break; + case KLockCount: + if (TotLock == 0) EndPass = 1; + else --TotLock; + break; + default: + fprintf(stderr, "\nInvalid stop switch\n"); + exit(SS$_ABORT); + } + + s = sys$deq(LksbSon.lksb$l_lkid, 0, 0, 0); + if (! $VMS_STATUS_SUCCESS(s)) exit(s); + + if (!EndPass) { + s = sys$enq(0, LCK$K_EXMODE, &LksbPar, 0, &ParResNameD, + 0, &ParLockCompletionAST, 0, 0, 0, 0, 0, 0); + if (! $VMS_STATUS_SUCCESS(s)) exit(s); + ++LockCount; + } +} + +static void ParLockCompletionAST(int i) { + ParDoLock(i); +} + +#ifdef __cplusplus +static void TimerAST(...) { +#else +static void TimerAST() { +#endif + EndPass = 1; +} + + + +main (int argc, char *argv[]) { + int s; + int i; + int typeTest = 0; + + + printf("%s %s, J.F. Pi�ronne, jf.pieronne@laposte.net\n", __DATE__, __TIME__); + + if (argc < 2) { + printf("usage lockperf n\n"); + printf(" n : 0 lock parent et sleep\n"); + printf(" 1 test sur lock fils\n"); + printf(" 2 test sur lock parent\n"); + exit(SS$_INSFARG); + } + else sscanf(argv[1], "%d", &typeTest); + + if ((typeTest < 0) || (typeTest > 2)) exit(SS$_INVARG); + s = sys$enqw( + 0, + LCK$K_NLMODE, + &LksbPar, + 0, + &ParResNameD, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0); + if (! $VMS_STATUS_SUCCESS(s)) exit(s); + + if (typeTest == 0) { + s = sys$enqw(0, LCK$K_NLMODE, &LksbSon, 0, &SonResNameD, + LksbPar.lksb$l_lkid, 0, 0, 0, 0, 0, 0, 0); + if (! $VMS_STATUS_SUCCESS(s)) exit(s); + sleep(300); + exit(s); + } + + InteractiveQueries(); + + for(i = 0; i < Pass; ++i) { + Stat_s* sp = &(StatInfo[i]); + int tlock; + int j; + GENERIC_64 deltaTime; + + EndPass = 0; + switch (TypeStop) { + case KDuration: + deltaTime.gen64$l_longword[0] = -10000000 * PassDuration; + deltaTime.gen64$l_longword[1] = -1; + s = sys$setimr(0, &deltaTime, TimerAST, 0, 0); + if (!$VMS_STATUS_SUCCESS(s)) exit(s); + break; + case KLockCount: + tlock = TotLock; + break; + default: + fprintf(stderr, "\nInvalid stop switch\n"); + exit(SS$_ABORT); + } + LockCount = 0; + lib$init_timer(); + s = sys$setast(0); + if (! $VMS_STATUS_SUCCESS(s)) exit(s); + if (typeTest == 1) + s = sys$enq(0, LCK$K_EXMODE, &LksbSon, 0, &SonResNameD, + LksbPar.lksb$l_lkid, &SonLockCompletionAST, 0, 0, 0, 0, 0, 0); + else if (typeTest == 2) { + s = sys$deq(LksbPar.lksb$l_lkid, 0, 0, 0); + if (! $VMS_STATUS_SUCCESS(s)) exit(s); + s = sys$enq(0, LCK$K_EXMODE, &LksbPar, 0, &ParResNameD, + 0, &ParLockCompletionAST, 0, 0, 0, 0, 0, 0); + } + if (! $VMS_STATUS_SUCCESS(s)) exit(s); + s = sys$setast(1); + if (! $VMS_STATUS_SUCCESS(s)) exit(s); + while (!EndPass) { + s = sys$hiber(); + if (!$VMS_STATUS_SUCCESS(s)) exit(s); + } + j = 2; + s = lib$stat_timer(&j, &(sp->_cpu)); + if (!$VMS_STATUS_SUCCESS(s)) exit(s); + j = 1; + s = lib$stat_timer(&j, (unsigned int *)sp->_elapsed); + if (!$VMS_STATUS_SUCCESS(s)) exit(s); + if (TypeStop == KLockCount) TotLock = tlock; + StatInfo[i]._lockCount = LockCount; + } + + for(i = 0; i < Pass; ++i) { + Stat_s* sp = &(StatInfo[i]); + printf("\t%5d locks\t%2d us/lock\t%4d locks/s\n", sp->_lockCount, + - sp->_elapsed[0] / 10 / sp->_lockCount, + - (int)((double)(sp->_lockCount) * 10000000.0 / sp->_elapsed[0])); + } + + + exit(s); +} +