[Info-vax] K-mutex
Pierre
pierre.bru at gmail.com
Thu Dec 15 10:53:40 EST 2011
I un-buried this test program I was using while implementing my Kmutex
functionality. it is as-is from my old developments archive. hope
it'll help.
---------------------------------------------------------
#include <ssdef.h>
#include <stsdef.h>
#include <lckdef.h>
#include <lkidef.h>
#include <libdef.h>
#include <otsdef.h>
#include <descrip.h>
#include <string.h>
#include <starlet.h>
#include <lib$routines.h>
#include <ots$routines.h>
typedef unsigned int ULONG;
typedef unsigned short UWORD;
typedef struct { UWORD status; UWORD _reserved; ULONG lockid; union
{ char _valblk[16]; int maxsub; } valblk; } LKSB;
#define RESNAM_MAXLEN 31
#define SUBNAM_LEN 10
typedef char RESNAME[RESNAM_MAXLEN+1];
typedef struct { RESNAME resname; LKSB lksb; } LOCKINFO;
typedef struct { void *myself; LOCKINFO master; LOCKINFO curr_sub;
LOCKINFO prev_sub;} RESOURCE;
void check ( ULONG status ) {
if (!$VMS_STATUS_SUCCESS(status)) { lib$stop(status); }
}
void tracking_ast(RESOURCE *resource) {
ULONG status;
ULONG rank ;
struct dsc$descriptor_s subname_d = { 0, DSC$K_DTYPE_T, DSC
$K_CLASS_S, NULL };
if (resource->curr_sub.lksb.status == SS$_NORMAL) {
/***
status = sys$enqw( 0, LCK$K_NLMODE, &(resource->prev_sub.lksb),
LCK$M_CONVERT, 0,0,0,0,0,0,0 );
check(status);
check(resource->prev_sub.lksb.status);
***/
status = sys$deq( resource->prev_sub.lksb.lockid, 0,0,0 );
check(status);
memcpy(&(resource->prev_sub), &(resource->curr_sub),
sizeof(LOCKINFO));
subname_d.dsc$w_length = SUBNAM_LEN;
subname_d.dsc$a_pointer = &(resource->prev_sub.resname[0]) ;
status = ots$cvt_tu_l( &subname_d, &rank );
check(status);
rank -- ;
if (rank > 0) {
subname_d.dsc$w_length = SUBNAM_LEN;
subname_d.dsc$a_pointer = &(resource->curr_sub.resname[0]) ;
status = ots$cvt_l_tu( &rank, &subname_d, SUBNAM_LEN);
check(status);
resource->curr_sub.resname[SUBNAM_LEN]='\0';
status = sys$enq( 0, LCK$K_EXMODE, &(resource->curr_sub.lksb),
LCK$M_NODLCKWT, &subname_d, resource->master.lksb.lockid,
tracking_ast, (__int64)resource, 0,0,0 ) ;
check(status) ;
}
}
}
int main (int argc, char* argv[]) {
ULONG status;
#define MAXUSERS 3
char resname[] = "MASTER" ;
RESOURCE resource;
struct dsc$descriptor_s resname_d = { 0, DSC$K_DTYPE_T, DSC
$K_CLASS_S, NULL };
struct dsc$descriptor_s subname_d = { 0, DSC$K_DTYPE_T, DSC
$K_CLASS_S, NULL };
/* init resource */
resource.myself = &resource ;
strncpy(resource.master.resname, resname, RESNAM_MAXLEN) ;
resname_d.dsc$w_length = strlen(resource.master.resname) ;
resname_d.dsc$a_pointer = &resource.master.resname[0] ;
status = sys$enqw( 0, LCK$K_EXMODE, &resource.master.lksb,
LCK$M_VALBLK, &resname_d, 0,0,0,0,0,0 );
check(status) ;
check(resource.master.lksb.status);
if (resource.master.lksb.valblk.maxsub == 0) {
resource.master.lksb.valblk.maxsub = MAXUSERS ;
} else if (resource.master.lksb.valblk.maxsub != MAXUSERS ) {
lib$stop(2); /* maxsub must be same for all processes */
}
status = sys$enqw( 0, LCK$K_NLMODE, &resource.master.lksb,
LCK$M_VALBLK | LCK$M_CONVERT, 0,0,0,0,0,0,0 );
check(status) ;
check(resource.master.lksb.status);
/* acquire resource */
subname_d.dsc$w_length = SUBNAM_LEN;
subname_d.dsc$a_pointer = &resource.prev_sub.resname[0] ;
status = ots$cvt_l_tu( &(MAXUSERS), &subname_d, SUBNAM_LEN );
check(status);
resource.prev_sub.resname[SUBNAM_LEN]='\0';
status = sys$enqw( 0, LCK$K_EXMODE, &resource.prev_sub.lksb,
0, &subname_d, resource.master.lksb.lockid, 0,0,0,0,0 );
check(status) ;
check(resource.prev_sub.lksb.status);
/* start usage tracking */
subname_d.dsc$w_length = SUBNAM_LEN;
subname_d.dsc$a_pointer = &resource.curr_sub.resname[0] ;
status = ots$cvt_l_tu( &(MAXUSERS-1), &subname_d, SUBNAM_LEN );
check(status);
resource.prev_sub.resname[SUBNAM_LEN]='\0';
status = sys$enq( 0, LCK$K_EXMODE, &resource.curr_sub.lksb,
LCK$M_NODLCKWT, &subname_d, resource.master.lksb.lockid,
tracking_ast, (__int64)&resource, 0,0,0 ) ;
check(status) ;
/* where interresting stuff is done while the resource is held */
{
char buffer[255];
$DESCRIPTOR( buffer_d, buffer );
$DESCRIPTOR( prompt_d, "> " );
status = lib$get_input(&buffer_d, &prompt_d);
check(status) ;
}
/* release resource */
status = sys$deq( resource.prev_sub.lksb.lockid, 0,0, LCK$M_DEQALL );
check(status);
status = sys$deq( resource.prev_sub.lksb.lockid, 0,0,0 );
check(status);
}
---------------------------------------------------------
More information about the Info-vax
mailing list