[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