Reentrant locking (#51)

This commit is contained in:
Patrick Stevens
2025-06-15 21:28:56 +01:00
committed by GitHub
parent 8b49b190ea
commit 3b1f916743
3 changed files with 23 additions and 11 deletions

View File

@@ -64,10 +64,14 @@ module System_Threading_Monitor =
failwith "TODO: throw ArgumentNullException" failwith "TODO: throw ArgumentNullException"
| EvalStackValue.ManagedPointer (ManagedPointerSource.Heap addr) -> | EvalStackValue.ManagedPointer (ManagedPointerSource.Heap addr) ->
match IlMachineState.getSyncBlock addr state with match IlMachineState.getSyncBlock addr state with
| None -> state |> IlMachineState.setSyncBlock addr (Some currentThread) | SyncBlock.Free ->
| Some _ -> state |> IlMachineState.setSyncBlock addr (SyncBlock.Locked (currentThread, 1))
failwith | SyncBlock.Locked (thread, counter) ->
"TODO: somehow need to block on the monitor; also what happens if this thread already has the lock?" if thread = currentThread then
state
|> IlMachineState.setSyncBlock addr (SyncBlock.Locked (thread, counter + 1))
else
failwith "TODO: somehow need to block on the monitor"
| EvalStackValue.ManagedPointer (ManagedPointerSource.LocalVariable _) -> | EvalStackValue.ManagedPointer (ManagedPointerSource.LocalVariable _) ->
failwith "TODO: local variable holds object to lock" failwith "TODO: local variable holds object to lock"
| lockObj -> failwith $"TODO: lock object in Monitor.ReliableEnter was {lockObj}" | lockObj -> failwith $"TODO: lock object in Monitor.ReliableEnter was {lockObj}"
@@ -75,11 +79,11 @@ module System_Threading_Monitor =
// Set result to True // Set result to True
let state = let state =
match outVar with match outVar with
| Null -> failwith "logic error" | ManagedPointerSource.Null -> failwith "logic error"
| LocalVariable (sourceThread, methodFrame, whichVar) -> | ManagedPointerSource.LocalVariable (sourceThread, methodFrame, whichVar) ->
state state
|> IlMachineState.setLocalVariable sourceThread methodFrame whichVar (CliType.OfBool true) |> IlMachineState.setLocalVariable sourceThread methodFrame whichVar (CliType.OfBool true)
| Heap addr -> failwith "todo: managed heap" | ManagedPointerSource.Heap addr -> failwith "todo: managed heap"
(state, WhatWeDid.Executed) |> ExecutionResult.Stepped (state, WhatWeDid.Executed) |> ExecutionResult.Stepped
@@ -95,8 +99,14 @@ module System_Threading_Monitor =
failwith "TODO: throw ArgumentNullException" failwith "TODO: throw ArgumentNullException"
| EvalStackValue.ManagedPointer (ManagedPointerSource.Heap addr) -> | EvalStackValue.ManagedPointer (ManagedPointerSource.Heap addr) ->
match IlMachineState.getSyncBlock addr state with match IlMachineState.getSyncBlock addr state with
| Some t when t = thread -> state |> IlMachineState.setSyncBlock addr None | SyncBlock.Free -> failwith "TODO: throw SynchronizationLockException"
| _ -> failwith "TODO: throw SynchronizationLockException" | SyncBlock.Locked (holdingThread, count) ->
if thread <> holdingThread then
failwith "TODO: throw SynchronizationLockException"
else if count = 1 then
IlMachineState.setSyncBlock addr SyncBlock.Free state
else
IlMachineState.setSyncBlock addr (SyncBlock.Locked (holdingThread, count - 1)) state
| EvalStackValue.ManagedPointer (ManagedPointerSource.LocalVariable _) -> | EvalStackValue.ManagedPointer (ManagedPointerSource.LocalVariable _) ->
failwith "TODO: local variable holds object to lock" failwith "TODO: local variable holds object to lock"
| lockObj -> failwith $"TODO: lock object in Monitor.ReliableEnter was {lockObj}" | lockObj -> failwith $"TODO: lock object in Monitor.ReliableEnter was {lockObj}"

View File

@@ -857,7 +857,7 @@ module IlMachineState =
{ {
Fields = Map.ofList fields Fields = Map.ofList fields
Type = TypeInfoCrate.make typeInfo Type = TypeInfoCrate.make typeInfo
SyncBlock = None SyncBlock = SyncBlock.Free
} }
let alloc, heap = state.ManagedHeap |> ManagedHeap.AllocateNonArray o let alloc, heap = state.ManagedHeap |> ManagedHeap.AllocateNonArray o

View File

@@ -2,7 +2,9 @@ namespace WoofWare.PawPrint
open System.Collections.Immutable open System.Collections.Immutable
type SyncBlock = ThreadId option type SyncBlock =
| Free
| Locked of lockingThread : ThreadId * reentrancyCount : int
type AllocatedNonArrayObject = type AllocatedNonArrayObject =
{ {