Commit e4af4b74 authored by Maxime Perrotin's avatar Maxime Perrotin

Refactor the interface to pohiada (in progress)

parent f37dd0b4
......@@ -477,7 +477,8 @@ package body TASTE.AADL_Parser is
declare
Thread : constant AADL_Thread :=
(Name => To_Lower (To_String (F.Name))
& "_" & PI.Name,
& "_" & PI.Name,
Partition_Name => US (Partition_Name),
RCM => US (PI.RCM'Img),
Need_Mutex => (F.Provided.Length > 1),
Entry_Port_Name => PI.Name,
......
......@@ -141,6 +141,7 @@ package body TASTE.Concurrency_View is
return Result : constant Translate_Set :=
T.PI.To_Template -- Template of the PI used to create the thread
& Assoc ("Thread_Name", To_String (T.Name))
& Assoc ("Partition_Name", To_String (T.Partition_Name))
& Assoc ("Entry_Port_Name", To_String (T.Entry_Port_Name))
& Assoc ("RCM", To_String (T.RCM))
& Assoc ("Need_Mutex", T.Need_Mutex)
......@@ -214,7 +215,8 @@ package body TASTE.Concurrency_View is
is
Partition : constant CV_Partition :=
CV.Nodes (Node_Name).Partitions (Partition_Name);
Thread_Names : Tag;
Thread_Names,
Thread_Has_Param : Vector_Tag;
Block_Names : Vector_Tag;
Block_Languages : Vector_Tag;
Blocks : Unbounded_String;
......@@ -290,6 +292,12 @@ package body TASTE.Concurrency_View is
Threads := Threads & Newline & Result;
Part_Threads := Part_Threads & Newline & Result;
Thread_Names := Thread_Names & Name;
-- Set boolean to true if thread has a param
-- That helps backend to know if POHI has generated
-- the "types" package.
Thread_Has_Param := Thread_Has_Param &
(T.PI.Params.Length > 0);
All_Thread_Names := All_Thread_Names & Name;
for P of T.Output_Ports loop
for Part_Threads of Partition.Threads loop
......@@ -396,6 +404,7 @@ package body TASTE.Concurrency_View is
Partition_Assoc := Partition.Deployment_Partition.To_Template
& Assoc ("Threads", Part_Threads)
& Assoc ("Thread_Names", Thread_Names)
& Assoc ("Thread_Has_Param", Thread_Has_Param)
& Assoc ("Node_Name", Node_Name)
& Assoc ("Blocks", Blocks)
& Assoc ("Block_Names", Block_Names)
......
......@@ -70,6 +70,7 @@ package TASTE.Concurrency_View is
type AADL_Thread is tagged
record
Name : Unbounded_String;
Partition_Name : Unbounded_String;
RCM : Unbounded_String;
Need_Mutex : Boolean := False;
Entry_Port_Name : Unbounded_String;
......
@@-- The following tags are available in this template:
@@--
@@-- @_Thread_Name_@ : Thread name
@@-- @_Partition_Name_@ : Partition containing this thread
@@-- @_Entry_Port_Name_@ : Name of the PI
@@-- @_RCM_@ : One of "CYCLIC_OPERATION", "SPORADIC_OPERATION"
@@-- @_Need_Mutex_@ : True if the PI is shared with others in the protected block
......@@ -42,7 +43,7 @@ features
@@IF@@ @_Use_POHIC_@
Compute_Entrypoint_Source_Text => "call_@_LOWER:Thread_Name_@"; };
@@ELSE@@
Compute_Entrypoint_Source_Text => "@_Thread_Name_@_Wrappers.@_Entry_Port_Name_@"; };
Compute_Entrypoint_Source_Text => "@_CAPITALIZE:Partition_Name_@_Polyorb_Interface.@_CAPITALIZE:Thread_Name_@_@_Entry_Port_Name_@"; };
@@END_IF@@
@@END_IF@@
@@TABLE@@
......@@ -61,7 +62,7 @@ properties
@@IF@@ @_Use_POHIC_@
Initialize_Entrypoint_Source_Text => "init_@_LOWER:Pro_Block_Name_@";
@@ELSE@@
Initialize_Entrypoint_Source_Text => "@_Thread_Name_@_Wrappers.C_Init_@_Thread_Name_@";
Initialize_Entrypoint_Source_Text => "@_CAPITALIZE:Partition_Name_@_Polyorb_Interface.@_CAPITALIZE:Thread_Name_@_Init";
@@END_IF@@
@@INLINE( )(\n )()@@
@@IF@@ @_RCM_@ = "SPORADIC_OPERATION"
......@@ -70,7 +71,7 @@ properties
@@IF@@ @_Use_POHIC_@
Compute_Entrypoint_Source_Text => "call_@_LOWER:Thread_Name_@";
@@ELSE@@
Compute_Entrypoint_Source_Text => "@_Thread_Name_@_Wrappers.@_Entry_Port_Name_@";
Compute_Entrypoint_Source_Text => "@_CAPITALIZE:Partition_Name_@_Polyorb_Interface.@_CAPITALIZE:Thread_Name_@_@_Entry_Port_Name_@";
@@END_IF@@
Dispatch_Protocol => Periodic;
@@END_IF@@
......
......@@ -2,7 +2,8 @@
@@--
@@-- @_Name_@ : Partition name (usually the name of the binary)
@@-- @_Threads_@ : Code generated for the threads
@@-- @_Thread_Names_@ : Tag: list of thread names
@@-- @_Thread_Names_@ : Vector Tag: list of thread names
@@-- @_Thread_Has_Param_@ : |_ true if the thread has a param
@@-- @_Node_Name_@ : Name of the node containing this partition
@@-- @_Blocks_@ : Code generated for protected functions
@@-- @_Block_Names@ : Vector Tag: list of block (user functions) names
......
......@@ -50,7 +50,7 @@ project @_CAPITALIZE:Name_@ is
-- following to be updated with all relevant source dirs
for Source_Dirs use
(".",
("@_LOWER:Name_@",
"/home/taste/tool-inst/include/ocarina/runtime/polyorb-hi-ada",
"../../dataview/C",
@@IF@@ @_Need_Ada_@ = TRUE
......
@@-- Specify the file name for a protected block
@@-- @_Block_Name_@ is available.
@@-- Don't specify anything if you don't want the file to be created
@_LOWER:Block_Name_@_block.ads
@@-- Specify the file name for a partition
@@-- @_Partition_Name_@ is available.
@@-- Don't specify anything if you don't want the file to be created
@_LOWER:Partition_Name_@/required_interfaces.ads
@@-- Specify the file name for a thread
@@-- @_Thread_Name_@ is available.
@@-- Don't specify anything if you don't want the file to be created
@_LOWER:Thread_Name_@_async_ri_wrappers.ads
......@@ -15,3 +15,10 @@
@@-- @_Thread_Dst_Name_@ : Vector tag : connection thread name (dest)
@@-- @_Thread_Src_Port_@ : Vector tag : connection port name (source)
@@-- @_Thread_Dst_Port_@ : Vector tag : connection port name (dest)
with Interfaces.C;
package Required_Interfaces is
-- generated from templates/concurrency_view/ada_ri_wrappers_source/partition.tmplt
@_Threads'Indent_@
end Required_Interfaces;
......@@ -17,10 +17,8 @@
@@-- @_IF_Property_Names_@, _Values_@ : user properties (vector tag)
@@--
@@-- Matrix of output ports: Remote thread/corresponding remote PI @_Name_@
with Interfaces.C;
package @_CAPITALIZE:Thread_Name_@_Async_RI_Wrappers is
package @_CAPITALIZE:Thread_Name_@ is
--- generated from templates/concurrency_view/ada_ri_wrappers_source/thread.tmplt
@@INLINE( )(\n )(\n)@@
@@TABLE@@
@@IF@@ @_Remote_PI_Sorts'Length_@ > 0
......@@ -32,5 +30,4 @@ package @_CAPITALIZE:Thread_Name_@_Async_RI_Wrappers is
@@END_IF@@
@@END_TABLE@@
@@END_INLINE@@
end @_CAPITALIZE:Thread_Name_@_Async_RI_Wrappers;
end @_CAPITALIZE:Thread_Name_@;
......@@ -7,19 +7,13 @@
@@-- @_Protected_PIs_@ : Protected Provided interfaces (from pi.tmplt)
@@-- @_Unprotected_PIs_@ : Unprotected Provided interfaces (from pi.tmplt)
@@-- @_Required_@ : Required interfaces (from ri.tmplt)
@@IF@@ @_Language_@ = SDL or @_Language_@ = Ada
with @_CAPITALIZE:Name_@;
@@END_IF@@
package body @_CAPITALIZE:Name_@_Block is
package body @_CAPITALIZE:Name_@ is
@@IF@@ @_Protected_PIs_@ /= ""
@@IF@@ @_Protected_PIs_@ /= ""
protected body @_CAPITALIZE:Name_@_Protected is
@_Protected_PIs'Indent_@
end @_CAPITALIZE:Name_@_Protected;
@@END_IF@@
@@END_IF@@
@_Unprotected_PIs'Indent_@
end @_CAPITALIZE:Name_@_Block;
end @_CAPITALIZE:Name_@;
@@-- Specify the file name for a protected block
@@-- @_Block_Name_@ is available.
@@-- Don't specify anything if you don't want the file to be created
@_LOWER:Block_Name_@_block.adb
@@-- Specify the file name for a partition
@@-- @_Partition_Name_@ is available.
@@-- Don't specify anything if you don't want the file to be created
@_LOWER:Partition_Name_@/@_LOWER:Partition_Name_@_polyorb_interface.adb
@@-- Specify the file name for a thread
@@-- @_Thread_Name_@ is available.
@@-- Don't specify anything if you don't want the file to be created
@_LOWER:Thread_Name_@_wrappers.adb
......@@ -3,6 +3,7 @@
@@-- @_Name_@ : Partition name (usually the name of the binary)
@@-- @_Threads_@ : Code generated for the threads
@@-- @_Thread_Names_@ : Tag: list of thread names
@@-- @_Thread_Has_Param_@ : |_ true if the thread has a param
@@-- @_Node_Name_@ : Name of the node containing this partition
@@-- @_Blocks_@ : Code generated for protected functions
@@-- @_Coverage_@ : True if user requested code coverage enable
......@@ -15,3 +16,8 @@
@@-- @_Thread_Dst_Name_@ : Vector tag : connection thread name (dest)
@@-- @_Thread_Src_Port_@ : Vector tag : connection port name (source)
@@-- @_Thread_Dst_Port_@ : Vector tag : connection port name (dest)
package body @_CAPITALIZE:Name_@_Polyorb_Interface is
-- generated from templates/concurrency_view/ada_wrappers_body/partition.tmplt
@_Blocks'Indent_@
@_Threads'Indent_@
end @_CAPITALIZE:Name_@_Polyorb_Interface;
......@@ -19,44 +19,34 @@
@@--
@@-- Matrix of output ports: Remote thread/corresponding remote PI @_Name_@
@@IF@@ @_Param_Names'Length_@ > 0
with Interfaces.C;
@@TABLE@@
procedure @_CAPITALIZE:Thread_Name_@_@_CAPITALIZE:Entry_Port_Name_@
(dummy_Entity : Entity_Type; Param_Buffer : @_REPLACE_ALL((-)/_):Param_Types_@_Buffer_Impl)
is
@@END_TABLE@@
@@ELSE@@
procedure @_CAPITALIZE:Thread_Name_@_@_CAPITALIZE:Entry_Port_Name_@
(dummy_Entity : Entity_Type)
is
@@END_IF@@
package body @_CAPITALIZE:Thread_Name_@_Wrappers is
@@INLINE( )()(\n)@@
@@IF@@ @_Param_Names'Length_@ > 0
@@TABLE@@
procedure @_CAPITALIZE:Entry_Port_Name_@ (dummy_Entity : Entity_Type; Param_Buffer : @_REPLACE_ALL((-)/_):Param_Types_@_Buffer_Impl) is
@@END_TABLE@@
@@ELSE@@
procedure @_CAPITALIZE:Entry_Port_Name_@ (dummy_Entity : Entity_Type) is
@@END_IF@@
@@END_INLINE@@
@@IF@@ @_Param_Names'Length_@ > 0
@@TABLE@@
@_CAPITALIZE:Param_Names_@_AdaBuffer : Interfaces.C.char_array (1 .. Interfaces.C.size_t (Param_Buffer.Length)) with Import;
for @_CAPITALIZE:Param_Names_@_AdaBuffer'Address use Param_Buffer'Address;
@@END_TABLE@@
begin
@@IF@@ @_Need_Mutex_@
@_CAPITALIZE:Pro_Block_Name_@_Block.@_CAPITALIZE:Pro_Block_Name_@_Protected.@_CAPITALIZE:Entry_Port_Name_@
@@ELSE@@
@_CAPITALIZE:Pro_Block_Name_@_Block.@_CAPITALIZE:Entry_Port_Name_@
@@END_IF@@
(@_CAPITALIZE:Param_Names_@_AdaBuffer, @_CAPITALIZE:Param_Names_@_AdaBuffer'Length);
@@IF@@ @_Param_Names'Length_@ > 0
@@TABLE@@
@_CAPITALIZE:Param_Names_@_AdaBuffer : Interfaces.C.char_array (1 .. Interfaces.C.size_t (Param_Buffer.Length)) with Import;
for @_CAPITALIZE:Param_Names_@_AdaBuffer'Address use Param_Buffer'Address;
@@END_TABLE@@
begin
@@IF@@ @_Need_Mutex_@
@_CAPITALIZE:Pro_Block_Name_@.@_CAPITALIZE:Pro_Block_Name_@_Protected.@_CAPITALIZE:Entry_Port_Name_@
@@ELSE@@
@_CAPITALIZE:Pro_Block_Name_@.@_CAPITALIZE:Entry_Port_Name_@
@@END_IF@@
(@_CAPITALIZE:Param_Names_@_AdaBuffer, @_CAPITALIZE:Param_Names_@_AdaBuffer'Length);
@@ELSE@@
begin
@@IF@@ @_Need_Mutex_@
@_CAPITALIZE:Pro_Block_Name_@.@_CAPITALIZE:Pro_Block_Name_@_Protected.@_CAPITALIZE:Entry_Port_Name_@;
@@ELSE@@
begin
@@IF@@ @_Need_Mutex_@
@_CAPITALIZE:Pro_Block_Name_@_Block.@_CAPITALIZE:Pro_Block_Name_@_Protected.@_CAPITALIZE:Entry_Port_Name_@;
@@ELSE@@
@_CAPITALIZE:Pro_Block_Name_@_Block.@_CAPITALIZE:Entry_Port_Name_@;
@@END_IF@@
@_CAPITALIZE:Pro_Block_Name_@.@_CAPITALIZE:Entry_Port_Name_@;
@@END_IF@@
end @_CAPITALIZE:Entry_Port_Name_@;
-- This is the list of remote threads/RIs :
@@TABLE@@
-- @_Remote_Threads_@.@_Remote_PIs_@
@@END_TABLE@@
end @_CAPITALIZE:Thread_Name_@_Wrappers;
@@END_IF@@
end @_CAPITALIZE:Thread_Name_@_@_CAPITALIZE:Entry_Port_Name_@;
......@@ -7,22 +7,21 @@
@@-- @_Protected_PIs_@ : Protected Provided interfaces (from pi.tmplt)
@@-- @_Unprotected_PIs_@ : Unprotected Provided interfaces (from pi.tmplt)
@@-- @_Required_@ : Required interfaces (from ri.tmplt)
package @_CAPITALIZE:Name_@ is
-- generated from templates/concurrency_view/ada_wrappers_source/block.tmplt
with Interfaces.C;
package @_CAPITALIZE:Name_@_Block is
-- This package interfaces with the user code directly
-- It may contain a protected object if a PI requires mutual exclusion
procedure Init
with Import, Convention => C, Link_Name => "init_@_LOWER:Name_@";
@@IF@@ @_Protected_PIs_@ /= ""
@@IF@@ @_Protected_PIs_@ /= ""
protected @_CAPITALIZE:Name_@_Protected is
@_Protected_PIs'Indent_@
end @_CAPITALIZE:Name_@_Protected;
@@END_IF@@
@@END_IF@@
@_Unprotected_PIs'Indent_@
end @_CAPITALIZE:Name_@_Block;
end @_CAPITALIZE:Name_@;
@@-- Specify the file name for a protected block
@@-- @_Block_Name_@ is available.
@@-- Don't specify anything if you don't want the file to be created
@_LOWER:Block_Name_@_block.ads
@@-- Specify the file name for a partition
@@-- @_Partition_Name_@ is available.
@@-- Don't specify anything if you don't want the file to be created
@_LOWER:Partition_Name_@/@_LOWER:Partition_Name_@_polyorb_interface.ads
@@-- Specify the file name for a thread
@@-- @_Thread_Name_@ is available.
@@-- Don't specify anything if you don't want the file to be created
@_LOWER:Thread_Name_@_wrappers.ads
......@@ -2,16 +2,54 @@
@@--
@@-- @_Name_@ : Partition name (usually the name of the binary)
@@-- @_Threads_@ : Code generated for the threads
@@-- @_Thread_Names_@ : Tag: list of thread names
@@-- @_Thread_Names_@ : Vector Tag: list of thread names
@@-- @_Thread_Has_Param_@ : |_ true if the thread has a param
@@-- @_Node_Name_@ : Name of the node containing this partition
@@-- @_Blocks_@ : Code generated for protected functions
@@-- @_Block_Names@ : Vector Tag: list of block (user functions) names
@@-- @_Block_Languages_@ : |_ Corresponding implementation language
@@-- @_Coverage_@ : True if user requested code coverage enable
@@-- @_Package_Name_@ : AADL Package name for the target (e.g. ocarina_porocessors_x86)
@@-- @_CPU_Name_@ : CPU Name (e.g. x86_linux)
@@-- @_CPU_Platform_@ : AADL CPU_Platform (e.g. PLATFORM_NATIVE)
@@-- @_CPU_Classifier_@ : AADL CPU Classifier (e.g. ocarina_processors_x86::x86.linux)
@@-- @_VP_Name_@ : Virtual processor name on which the partition is bounded
@@-- @_VP_Platform_@ : Virtual processor platform (e.g. PLATFORM_AIR)
@@-- @_VP_Classifier_@ : Virtual processor classifier
@@-- @_Ada_Runtime_@ : Set if CPU_Platform = PLATFORM_GNAT_RUNTIME
@@-- @_Bound_Functions_@ : List of user functions from Interface view
@@-- @_Thread_Src_Name_@ : Vector tag : connection thread name (source)
@@-- @_Thread_Dst_Name_@ : Vector tag : connection thread name (dest)
@@-- @_Thread_Src_Port_@ : Vector tag : connection port name (source)
@@-- @_Thread_Dst_Port_@ : Vector tag : connection port name (dest)
@@-- @_In_Port_Names_@ : Vector tag: input ports of the partition
@@-- @_In_Port_Thread_Name_@ : |_ corresponding thread inside the partition
@@-- @_In_Port_Type_Name_@ : |_ corresponding parameter type name (optional)
@@-- @_Out_Port_Names_@ : Vector tag: output ports of the partition
@@-- @_Out_Port_Thread_Name_@ : |_ corresponding thread inside the partition
@@-- @_Out_Port_Type_Name_@ : |_ corresponding parameter type name (optional)
with Interfaces.C;
with PolyORB_HI_Generated.Deployment;
use PolyORB_HI_Generated.Deployment;
@@TABLE@@
@@IF@@ @_Thread_Has_Param_@
@@SET@@ Need_Types=True
@@END_IF@@
@@END_TABLE@@
@@IF@@ @_Need_Types_@
with PolyORB_HI_Generated.Types;
use PolyORB_HI_Generated.Types;
@@END_IF@@
@@-- Make sure at least someone includes the user Ada packages (for compilation/elaboration)
@@TABLE@@
@@IF@@ @_Block_Languages_@ = SDL or @_Block_Languages_@ = Ada
with @_CAPITALIZE:Block_Names_@;
@@END_IF@@
@@END_TABLE@@
package @_CAPITALIZE:Name_@_Polyorb_Interface is
-- generated from templates/concurrency_view/ada_wrappers_source/partition.tmplt
@_Blocks'Indent_@
@_Threads'Indent_@
end @_CAPITALIZE:Name_@_Polyorb_Interface;
......@@ -4,7 +4,23 @@
@@-- @_Direction_@ : "PI" or "RI"
@@-- @_Kind_@ : The RCM Kind
@@-- @_Parent_Function_@ : The name of the function
@@-- @_Partition_Name_@ : Partition name for parent function
@@-- @_Param_Names_@ : List of parameter names
@@-- @_Param_Types_@ : |_ Corresponding parameter types
@@-- @_Param_Directions_@ : |_ Corresponding direction
@@-- @_Remote_Function_Names_@ : List of callees
@@-- @_Remote_Interface_Names_@ : |_ callee's interface name
@@-- @_Calling_Threads_@ : Calling threads of the containing block
-- generated from templates/concurrency_view/ada_wrappers_source/ri.tmplt
@@IF@@ @_Param_Names'Length_@ = 0
procedure @_CAPITALIZE:Name_@
@@ELSE@@
procedure @_CAPITALIZE:Name_@
@@INLINE( \()(;\n )(\);)@@
@@TABLE'ALIGN_ON(":")@@
@_CAPITALIZE:Param_Names_@ : Interfaces.C.char_array; @_CAPITALIZE:Param_Names_@_Size : Integer
@@END_TABLE@@
@@END_INLINE@@
@@END_IF@@
with Export, Convention => C, Link_Name => "vm_@_LOWER:Parent_Function_@_@_LOWER:Name_@";
......@@ -18,35 +18,16 @@
@@-- @_IF_Property_Names_@, _Values_@ : user properties (vector tag)
@@--
@@-- Matrix of output ports: Remote thread/corresponding remote PI @_Name_@
@@IF@@ @_Param_Names'Length_@ > 0
with PolyORB_HI_Generated.Types;
use PolyORB_HI_Generated.Types;
@@END_IF@@
with PolyORB_HI_Generated.Deployment;
use PolyORB_HI_Generated.Deployment;
with @_CAPITALIZE:Pro_Block_Name_@_Block;
package @_CAPITALIZE:Thread_Name_@_Wrappers is
-- This package is the interface to PolyORB-HI-Ada for provided interfaces
-- It calls the user code via the protected block that ensures
-- mutual exclusion of the interfaces.
-- generated from templates/concurrency_view/ada_wrappers_source/thread.tmplt
procedure @_CAPITALIZE:Thread_Name_@_Init renames @_CAPITALIZE:Pro_Block_Name_@.Init;
procedure C_Init_@_CAPITALIZE:Thread_Name_@ renames @_CAPITALIZE:Pro_Block_Name_@_Block.Init;
@@INLINE( )(\n )(\n)@@
@@IF@@ @_Param_Names'Length_@ > 0
@@TABLE@@
procedure @_CAPITALIZE:Entry_Port_Name_@ (dummy_Entity : Entity_Type; Param_Buffer : @_REPLACE_ALL((-)/_):Param_Types_@_Buffer_Impl);
@@END_TABLE@@
@@ELSE@@
procedure @_CAPITALIZE:Entry_Port_Name_@ (dummy_Entity : Entity_Type);
@@END_IF@@
@@END_INLINE@@
-- This is the list of remote threads/RIs :
@@TABLE@@
-- @_Remote_Threads_@.@_Remote_PIs_@
@@END_TABLE@@
end @_CAPITALIZE:Thread_Name_@_Wrappers;
@@IF@@ @_Param_Names'Length_@ > 0
@@TABLE@@
procedure @_CAPITALIZE:Thread_Name_@_@_CAPITALIZE:Entry_Port_Name_@
(dummy_Entity : Entity_Type; Param_Buffer : @_REPLACE_ALL((-)/_):Param_Types_@_Buffer_Impl);
@@END_TABLE@@
@@ELSE@@
procedure @_CAPITALIZE:Thread_Name_@_@_CAPITALIZE:Entry_Port_Name_@
(dummy_Entity : Entity_Type);
@@END_IF@@
......@@ -3,6 +3,7 @@
@@-- @_Name_@ : Partition name (usually the name of the binary)
@@-- @_Threads_@ : Code generated for the threads
@@-- @_Thread_Names_@ : Tag: list of thread names
@@-- @_Thread_Has_Param_@ : |_ true if the thread has a param
@@-- @_Node_Name_@ : Name of the node containing this partition
@@-- @_Blocks_@ : Code generated for protected functions
@@-- @_Block_Names@ : Vector Tag: list of block (user functions) names
......
@@-- The following tags are available in this template:
@@--
@@-- @_Thread_Name_@ : Thread name
@@-- @_Partition_Name_@ : Partition containing this thread
@@-- @_Entry_Port_Name_@ : Name of the PI
@@-- @_RCM_@ : One of "CYCLIC_OPERATION", "SPORADIC_OPERATION"
@@-- @_Need_Mutex_@ : True if the PI is shared with others in the protected block
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment