//This file was generated by the LASAL2 CodeGenerator  -- 
//Please, do not edit this file (it might be overwritten by the next generator run)
//{{LSL_DECLARATION

(*!
<Class
	Name               = "CriticalSection"
	Revision           = "0.4"
	GUID               = "{4DAF64E4-CD56-4313-A2F0-DEADCB2D49E9}"
	RealtimeTask       = "false"
	CyclicTask         = "false"
	BackgroundTask     = "false"
	Sigmatek           = "true"
	OSInterface        = "false"
	HighPriority       = "false"
	Automatic          = "false"
	UpdateMode         = "Prescan"
	IconPath           = ".\Class\CriticalSection\CriticalSection.ico"
	SharedCommandTable = "true"
	Objectsize         = "(284,120)"
	Comment            = "instance of class is used to ensure &quot;critical sections&quot;&#13;&#10;multiple instances of class are possibly and recommended">
	<Channels>
		<Server Name="ClassSvr" GUID="{1E1BE5AD-5ABA-4898-A92E-33A1C45CE749}" Visualized="false" Initialize="false" WriteProtected="true" Retentive="false"/>
	</Channels>
	<RevDoku>
		<Owner Company="sigmatek" Author="kolott"/>
		<Dokumentation Revision="0.4" Date="2013-09-19" Author="kolott" Company="sigmatek" Description="identifier (name) includes address of object"/>
		<Dokumentation Revision="0.3" Date="2013-09-05" Author="kolott" Company="sigmatek" Description="icon added"/>
		<Dokumentation Revision="0.2" Date="2012-09-28" Author="kolott" Company="sigmatek" Description="wipe limitation of 128 different sections"/>
		<Dokumentation Revision="0.1" Date="2012-06-12" Author="kolott" Company="sigmatek" Description="release"/>
	</RevDoku>
</Class>
*)
CriticalSection : CLASS
  //Servers:
	ClassSvr 	: SvrChCmd_UDINT;
  //Clients:
  //Variables:
  //Functions:
	
	FUNCTION CriticalSection
		VAR_OUTPUT
			ret_code 	: ConfStates;
		END_VAR;
	
	FUNCTION VIRTUAL GLOBAL Init;
	
	FUNCTION MakeSectionName
		VAR_INPUT
			ptr 	: ^USINT;
		END_VAR;
				//! <Function Comment="start critical section" Name="SectionStart"/>
	FUNCTION GLOBAL SectionStart;
				//! <Function Comment="stop critical section" Name="SectionStop"/>
	FUNCTION GLOBAL SectionStop;
	
	FUNCTION TAB HexTab;
  //Tables:
	FUNCTION @STD
		VAR_OUTPUT
			ret_code	: CONFSTATES;
		END_VAR;
	FUNCTION GLOBAL TAB @CT_;
END_CLASS;

//}}LSL_DECLARATION


FUNCTION GLOBAL TAB CriticalSection::@CT_
0$UINT,
2#0100000000000000$UINT, //TY_CRITICALSECTION
0$UINT, 4$UINT, (SIZEOF(::CriticalSection))$UINT, 
1$UINT, 0$UINT, 0$UINT, 
TO_UDINT(794617671), "CriticalSection", //Class
TO_UDINT(0), 0, 0$UINT, 0$UINT, //Baseclass
//Servers:
(::CriticalSection.ClassSvr.pMeth)$UINT, _CH_CMD$UINT, 2#0000000000000000$UINT, TO_UDINT(619352855), "ClassSvr", 
//Clients:
END_FUNCTION


#define USER_CNT_CriticalSection 0

TYPE
	_LSL_STD_VMETH	: STRUCT
			CmdTable	: CMDMETH;
			UserFcts	: ARRAY[0..USER_CNT_CriticalSection] OF ^Void;
	END_STRUCT;
END_TYPE

FUNCTION CriticalSection::@STD
	VAR_OUTPUT
		ret_code	: CONFSTATES;
	END_VAR
	VAR
		vmt	: _LSL_STD_VMETH;
	END_VAR

	//Command Methods
	InitCmdTable (nCmd := nSTDCMD + USER_CNT_CriticalSection, pCmd := #vmt.CmdTable);
	vmt.CmdTable.Init		:= #Init();
	ClassSvr.pMeth		:= StoreCmd (pCmd := #vmt.CmdTable, SHARED);

	IF ClassSvr.pMeth THEN
		ret_code	:= C_OK;
	ELSE
		ret_code	:= C_OUTOF_NEAR;
		RETURN;
	END_IF;
	ret_code	:= CriticalSection();

END_FUNCTION

//{{LSL_IMPLEMENTATION

#include <lsl_st_mt.h>

VAR_PRIVATE
  mt_api            : ^LSL_MT_TYPE;
END_VAR

FUNCTION CriticalSection::CriticalSection
	VAR_OUTPUT
		ret_code 	: ConfStates;
	END_VAR

	ret_code := C_OK;
  mt_api   := NIL;

END_FUNCTION

FUNCTION VIRTUAL GLOBAL CriticalSection::Init
  VAR
  	tmp : array[0..20] of usint;
  END_VAR
  
  if(mt_api = NIL) then
    if(OS_CILGet("LSL_MULTITASK", #mt_api$void)) THEN
      mt_api := NIL; 
    end_if;
  end_if;

  if(ClassSvr = 0) then
    if(mt_api <> NIL) then
      MakeSectionName(#tmp[0]);
      ClassSvr$^void := OS_MT_CreateSemaphore(MTSEMATYPE_MUTEX, 1, 0, #tmp[0]);
    end_if;
  end_if;
  
END_FUNCTION

FUNCTION CriticalSection::MakeSectionName
	VAR_INPUT
		ptr 	: ^USINT;
	END_VAR
  var
    hno : udint;
    ph, hextab : ^usint;
  end_var
  
  hno$^CriticalSection := this;
  hextab      := "0123456789ABCDEF";

  ptr$^udint^ := 16#5F78756D; ptr += 4; // mux_
  ph   := hextab + ((hno shr (32- 4)) and 16#0F);
  ptr^ := ph^; ptr += sizeof(usint);
  ph   := hextab + ((hno shr (32- 8)) and 16#0F);
  ptr^ := ph^; ptr += sizeof(usint);
  ph   := hextab + ((hno shr (32-12)) and 16#0F);
  ptr^ := ph^; ptr += sizeof(usint);
  ph   := hextab + ((hno shr (32-16)) and 16#0F);
  ptr^ := ph^; ptr += sizeof(usint);
  ph   := hextab + ((hno shr (32-20)) and 16#0F);
  ptr^ := ph^; ptr += sizeof(usint);
  ph   := hextab + ((hno shr (32-24)) and 16#0F);
  ptr^ := ph^; ptr += sizeof(usint);
  ph   := hextab + ((hno shr (32-28)) and 16#0F);
  ptr^ := ph^; ptr += sizeof(usint);
  ph   := hextab + ((hno shr (32-32)) and 16#0F);
  ptr^ := ph^; ptr += sizeof(usint);
  ptr^ := 0;

END_FUNCTION

FUNCTION GLOBAL CriticalSection::SectionStart

  if(ClassSvr <> 0) then
    OS_MT_WAIT(ClassSvr$^void); 
  end_if;

END_FUNCTION

FUNCTION GLOBAL CriticalSection::SectionStop

  if(ClassSvr <> 0) then
    OS_MT_SIGNAL(ClassSvr$^void); 
  end_if;

END_FUNCTION
