Skip to content

Commit

Permalink
grt-vpi: automatically free handlers for callbacks. Fix #1226
Browse files Browse the repository at this point in the history
  • Loading branch information
tgingold committed Apr 15, 2020
1 parent 90d7bfe commit 0c05fa8
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 8 deletions.
61 changes: 53 additions & 8 deletions src/grt/grt-vpi.adb
Original file line number Diff line number Diff line change
Expand Up @@ -1266,9 +1266,39 @@ package body Grt.Vpi is
-- Wrapper
procedure Call_Callback (Arg : System.Address)
is
Hand : constant vpiHandle := To_vpiHandle (Arg);
Hand : vpiHandle;
begin
Hand := To_vpiHandle (Arg);

-- Increase/decrease the reference counter as it is referenced by HAND.
Hand.Cb_Refcnt := Hand.Cb_Refcnt + 1;
Execute_Callback (Hand);
Hand.Cb_Refcnt := Hand.Cb_Refcnt - 1;

-- Free handlers if called once.
case Hand.Cb.Reason is
when cbEndOfCompile
| cbStartOfSimulation
| cbEndOfSimulation
| cbReadOnlySynch
| cbReadWriteSynch
| cbAfterDelay
| cbNextSimTime =>
pragma Assert (Hand.Cb_Refcnt = 1);
-- The handler has been removed from the queue, so the reference
-- counter has to be decremented and its value must be 0. Time
-- to free it.
Free (Hand);
when cbValueChange =>
-- The handler hasn't been removed from the queue, unless the
-- user did it while the callback was executed. If so, the
-- reference counter must now be 0 and we can free it.
if Hand.Cb_Refcnt = 0 then
Free (Hand);
end if;
when others =>
null;
end case;
end Call_Callback;

procedure Call_Valuechange_Callback (Arg : System.Address)
Expand Down Expand Up @@ -1324,6 +1354,9 @@ package body Grt.Vpi is
Res := new struct_vpiHandle (vpiCallback);
Res.Cb := Data.all;

-- There is one reference to the callback as it is registered.
Res.Cb_Refcnt := 1;

case Data.Reason is
when cbEndOfCompile =>
Append_Callback (g_cbEndOfCompile, Res);
Expand Down Expand Up @@ -1356,7 +1389,7 @@ package body Grt.Vpi is
(Cb_Next_Time_Step, Res.Cb_Handle, Oneshot,
Call_Callback'Access, To_Address (Res));
when others =>
dbgPut_Line ("vpi_register_cb: unknown reason");
dbgPut_Line ("vpi_register_cb: unknown callback reason");
Free (Res);
end case;

Expand All @@ -1383,11 +1416,15 @@ package body Grt.Vpi is
Res := 1;
Ref_Copy := Ref;
case Ref.Cb.Reason is
when cbValueChange =>
Delete_Callback (Ref.Cb_Handle);
when cbReadWriteSynch
| cbReadOnlySynch =>
when cbValueChange
| cbReadWriteSynch
| cbReadOnlySynch =>
Delete_Callback (Ref.Cb_Handle);
Ref.Cb_Refcnt := Ref.Cb_Refcnt - 1;
if Ref.Cb_Refcnt > 0 then
-- Do not free REF.
Ref_Copy := null;
end if;
when others =>
Res := 0;
Ref_Copy := null;
Expand Down Expand Up @@ -1419,8 +1456,16 @@ package body Grt.Vpi is
Trace (")");
Trace_Newline;
end if;
Ref_Copy := aRef;
Free (Ref_Copy);

case aRef.mType is
when vpiCallback =>
-- Callback are automatically freed.
null;
when others =>
Ref_Copy := aRef;
Free (Ref_Copy);
end case;

return 1;
end vpi_free_object;

Expand Down
2 changes: 2 additions & 0 deletions src/grt/grt-vpi.ads
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,8 @@ private
Cb_Prev, Cb_Next : vpiHandle;
Cb_Wire : Grt.Vcd.Verilog_Wire_Info;
Cb_Handle : Callbacks.Callback_Handle;
-- Number of reference to the handler by the simulation kernel.
Cb_Refcnt : Natural;
when others =>
Ref : VhpiHandleT;
end case;
Expand Down

0 comments on commit 0c05fa8

Please sign in to comment.