ReactOS  0.4.13-dev-1148-g9b75b67
dldetect.cpp File Reference
#include "udffs.h"
Include dependency graph for dldetect.cpp:

Go to the source code of this file.

Macros

#define UDF_BUG_CHECK_ID   UDF_FILE_DLD
 define the file specific bug-check id More...
 
#define RESOURCE_EVENT_TAG   'vEeR'
 Resource event (ExclusiveWaiters) More...
 
#define RESOURCE_SEMAFORE_TAG   'eSeR'
 Resource semaphore (SharedWaiters) More...
 
#define RESOURCE_TABLE_TAG   'aTeR'
 Resource owner table (OwnerTable) More...
 
#define DLD_MAX_REC_LEVEL   40
 Maxmum recurse level while exploring thread-resource aquisition graf. More...
 

Functions

VOID DLDInit (ULONG MaxThrdCount)
 Initialize deadlock detector. More...
 
VOID DLDFree (VOID)
 
PTHREAD_STRUCT DLDAllocFindThread (ULONG ThreadId)
 
PTHREAD_STRUCT DLDFindThread (ULONG ThreadId)
 
BOOLEAN DLDProcessResource (PERESOURCE Resource, PTHREAD_STRUCT ThrdStruct, ULONG RecLevel)
 TRUE Indicates deadlock. More...
 
BOOLEAN DLDProcessThread (PTHREAD_STRUCT ThrdOwner, PTHREAD_STRUCT ThrdStruct, PERESOURCE Resource, ULONG RecLevel)
 TRUE Indicates deadlock. More...
 
VOID DLDpWaitForResource (IN PERESOURCE Resource, IN DISPATCHER_HEADER *DispatcherObject, IN PTHREAD_STRUCT ThrdStruct)
 
VOID DLDpAcquireResourceExclusiveLite (IN PERESOURCE Resource, IN ERESOURCE_THREAD Thread, IN KIRQL oldIrql, IN ULONG BugCheckId, IN ULONG Line)
 
VOID DLDAcquireExclusive (PERESOURCE Resource, ULONG BugCheckId, ULONG Line)
 
POWNER_ENTRY DLDpFindCurrentThread (IN PERESOURCE Resource, IN ERESOURCE_THREAD Thread)
 
VOID DLDAcquireShared (PERESOURCE Resource, ULONG BugCheckId, ULONG Line, BOOLEAN WaitForExclusive)
 

Variables

ULONG MaxThreadCount = 0
 Maximum supported number of threads (initialized by DLDInit()) More...
 
PTHREAD_STRUCT DLDThreadTable
 Waiters table. More...
 
LARGE_INTEGER DLDpTimeout
 4 sec More...
 
ULONG DLDpResourceTimeoutCount = 0x2
 8 sec More...
 
THREAD_REC_BLOCK DLDThreadAcquireChain [DLD_MAX_REC_LEVEL]
 

Macro Definition Documentation

◆ DLD_MAX_REC_LEVEL

#define DLD_MAX_REC_LEVEL   40

Maxmum recurse level while exploring thread-resource aquisition graf.

Definition at line 36 of file dldetect.cpp.

◆ RESOURCE_EVENT_TAG

#define RESOURCE_EVENT_TAG   'vEeR'

Resource event (ExclusiveWaiters)

Definition at line 29 of file dldetect.cpp.

◆ RESOURCE_SEMAFORE_TAG

#define RESOURCE_SEMAFORE_TAG   'eSeR'

Resource semaphore (SharedWaiters)

Definition at line 31 of file dldetect.cpp.

◆ RESOURCE_TABLE_TAG

#define RESOURCE_TABLE_TAG   'aTeR'

Resource owner table (OwnerTable)

Definition at line 33 of file dldetect.cpp.

◆ UDF_BUG_CHECK_ID

#define UDF_BUG_CHECK_ID   UDF_FILE_DLD

define the file specific bug-check id

Definition at line 25 of file dldetect.cpp.

Function Documentation

◆ DLDAcquireExclusive()

VOID DLDAcquireExclusive ( PERESOURCE  Resource,
ULONG  BugCheckId,
ULONG  Line 
)

Definition at line 313 of file dldetect.cpp.

316  {
317 
318  KIRQL oldIrql;
319 
320  KeAcquireSpinLock(&Resource->SpinLock, &oldIrql);
321 
323 
324  if (!Resource->ActiveCount) goto SimpleAcquire;
325  if ((Resource->Flag & ResourceOwnedExclusive) && Resource->OwnerThreads[0].OwnerThread == Thread) {
326  Resource->OwnerThreads[0].OwnerCount++;
327  KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
328  return;
329  }
330 
331  DLDpAcquireResourceExclusiveLite(Resource, Thread, oldIrql,BugCheckId,Line);
332  return;
333 
334 SimpleAcquire:
335 
337  Resource->ActiveCount = 1;
338  Resource->OwnerThreads[0].OwnerThread = Thread;
339  Resource->OwnerThreads[0].OwnerCount = 1;
340 
341  KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
342 }
ULONG_PTR ERESOURCE_THREAD
Definition: extypes.h:208
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
UCHAR KIRQL
Definition: env_spec_w32.h:591
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:848
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
Definition: ncftp.h:79
VOID DLDpAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN ERESOURCE_THREAD Thread, IN KIRQL oldIrql, IN ULONG BugCheckId, IN ULONG Line)
Definition: dldetect.cpp:261
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define ResourceOwnedExclusive
Definition: dldetect.h:32

Referenced by DLDpAcquireResourceExclusiveLite().

◆ DLDAcquireShared()

VOID DLDAcquireShared ( PERESOURCE  Resource,
ULONG  BugCheckId,
ULONG  Line,
BOOLEAN  WaitForExclusive 
)

Definition at line 398 of file dldetect.cpp.

402 {
403 
404  KIRQL oldIrql;
405 
407  POWNER_ENTRY pOwnerEntry;
408 
409  KeAcquireSpinLock(&Resource->SpinLock, &oldIrql);
410 
411  if (!Resource->ActiveCount) {
413  Resource->ActiveCount = 1;
414  Resource->OwnerThreads[1].OwnerThread = Thread;
415  Resource->OwnerThreads[1].OwnerCount = 1;
416  KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
417  return;
418  }
419 
420  if (Resource->Flag & ResourceOwnedExclusive ) {
421  if (Resource->OwnerThreads[0].OwnerThread == Thread) {
422  Resource->OwnerThreads[0].OwnerCount++;
423  KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
424  return;
425  }
426 
427  pOwnerEntry = DLDpFindCurrentThread(Resource, 0);
428 
429  } else {
430  // owned shared by some thread(s)
431 
432  pOwnerEntry = DLDpFindCurrentThread(Resource, Thread);
433 
434  if (!WaitForExclusive && pOwnerEntry->OwnerThread == Thread) {
435  pOwnerEntry->OwnerCount++;
436  KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
437  return;
438  }
439 
440  if (!(Resource->NumberOfExclusiveWaiters)) {
441 
442  pOwnerEntry->OwnerThread = Thread;
443  pOwnerEntry->OwnerCount = 1;
444  Resource->ActiveCount++;
445  KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
446 
447  return;
448  }
449  }
450 
451  if (!(Resource->SharedWaiters)) {
453  KeInitializeSemaphore(Resource->SharedWaiters,0,0x7fffffff);
454  }
455 
456  Resource->NumberOfSharedWaiters++;
457 
459 
460 
461  // Set WaitingResource for current thread
462  ThrdStruct->WaitingResource = Resource;
463  ThrdStruct->BugCheckId = BugCheckId;
464  ThrdStruct->Line = Line;
465 
466  KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
467 
468  DLDpWaitForResource(Resource,&(Resource->SharedWaiters->Header),ThrdStruct);
469 
470  KeAcquireSpinLock(&Resource->SpinLock, &oldIrql);
471 
472  pOwnerEntry = DLDpFindCurrentThread(Resource, Thread);
473  pOwnerEntry->OwnerThread = Thread;
474  pOwnerEntry->OwnerCount = 1;
475 
476  ThrdStruct->WaitingResource = NULL;
477  ThrdStruct->ThreadId = 0;
478  ThrdStruct->BugCheckId = 0;
479  ThrdStruct->Line = 0;
480 
481  KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
482 
483  return;
484 
485 }
Definition: extypes.h:210
ULONG_PTR ERESOURCE_THREAD
Definition: extypes.h:208
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
PERESOURCE WaitingResource
Definition: dldetect.h:60
ERESOURCE_THREAD ThreadId
Definition: dldetect.h:59
ULONG Line
Definition: dldetect.h:62
PTHREAD_STRUCT DLDAllocFindThread(ULONG ThreadId)
Definition: dldetect.cpp:70
UCHAR KIRQL
Definition: env_spec_w32.h:591
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:848
struct _KSEMAPHORE * PKSEMAPHORE
smooth NULL
Definition: ftsmooth.c:416
ULONG OwnerCount
Definition: extypes.h:216
VOID NTAPI KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, IN LONG Count, IN LONG Limit)
Definition: semphobj.c:22
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define RESOURCE_SEMAFORE_TAG
Resource semaphore (SharedWaiters)
Definition: dldetect.cpp:31
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
ERESOURCE_THREAD OwnerThread
Definition: extypes.h:211
POWNER_ENTRY DLDpFindCurrentThread(IN PERESOURCE Resource, IN ERESOURCE_THREAD Thread)
Definition: dldetect.cpp:345
VOID DLDpWaitForResource(IN PERESOURCE Resource, IN DISPATCHER_HEADER *DispatcherObject, IN PTHREAD_STRUCT ThrdStruct)
Definition: dldetect.cpp:225
ULONG BugCheckId
Definition: dldetect.h:61
#define ResourceOwnedExclusive
Definition: dldetect.h:32
struct Line Line

◆ DLDAllocFindThread()

PTHREAD_STRUCT DLDAllocFindThread ( ULONG  ThreadId)

Definition at line 70 of file dldetect.cpp.

70  {
71  ULONG i = 0;
73  ULONG FirstEmpty = -1;
74 
75  while (i<MaxThreadCount) {
76  if (Temp->ThreadId == ThreadId) {
77  return Temp;
78  } else if (FirstEmpty == -1 && !Temp->ThreadId) {
79  FirstEmpty = i;
80  }
81  Temp++;
82  i++;
83  }
84  // Not found. Allocate new one.
85  if (i == MaxThreadCount) {
86  if (FirstEmpty == -1) {
87  UDFPrint(("Not enough table entries. Try to increase MaxThrdCount on next build"));
88  BrutePoint();
89  }
90  i = FirstEmpty;
91  }
92  Temp = DLDThreadTable + i;
93 
94  RtlZeroMemory(Temp, sizeof(THREAD_STRUCT));
95  Temp->ThreadId = ThreadId;
96 
97  return Temp;
98 }
#define UDFPrint(Args)
Definition: udffs.h:225
ERESOURCE_THREAD ThreadId
Definition: dldetect.h:59
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
ULONG MaxThreadCount
Maximum supported number of threads (initialized by DLDInit())
Definition: dldetect.cpp:39
PTHREAD_STRUCT DLDThreadTable
Waiters table.
Definition: dldetect.cpp:42
#define BrutePoint()
Definition: env_spec_w32.h:504
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261

Referenced by DLDAcquireShared(), and DLDpAcquireResourceExclusiveLite().

◆ DLDFindThread()

PTHREAD_STRUCT DLDFindThread ( ULONG  ThreadId)

Definition at line 100 of file dldetect.cpp.

100  {
101  ULONG i = 0;
103  ULONG FirstEmpty = -1;
104 
105 
106  while (i<MaxThreadCount) {
107  if (Temp->ThreadId == ThreadId) {
108  return Temp;
109  }
110  Temp++;
111  i++;
112  }
113 
114  return NULL;
115 }
ERESOURCE_THREAD ThreadId
Definition: dldetect.h:59
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
smooth NULL
Definition: ftsmooth.c:416
ULONG MaxThreadCount
Maximum supported number of threads (initialized by DLDInit())
Definition: dldetect.cpp:39
PTHREAD_STRUCT DLDThreadTable
Waiters table.
Definition: dldetect.cpp:42
unsigned int ULONG
Definition: retypes.h:1

Referenced by DLDProcessResource().

◆ DLDFree()

VOID DLDFree ( VOID  )

Definition at line 64 of file dldetect.cpp.

64  {
65 
67 
68 }
#define DLDFreePool(addr)
Definition: dldetect.h:26
PTHREAD_STRUCT DLDThreadTable
Waiters table.
Definition: dldetect.cpp:42

Referenced by DriverEntry().

◆ DLDInit()

VOID DLDInit ( ULONG  MaxThrdCount)

Initialize deadlock detector.

Parameters
MaxThrdCountMaximum supported number of threads

Definition at line 51 of file dldetect.cpp.

52  {
53  if (KeNumberProcessors>1) {
54  UDFPrint(("Deadlock Detector is designed for uniprocessor machines only!\n"));
55  BrutePoint();
56  }
57  DLDpTimeout.QuadPart = -40000000I64;
58 
59  MaxThreadCount = MaxThrdCount;
62 }
#define UDFPrint(Args)
Definition: udffs.h:225
LARGE_INTEGER DLDpTimeout
4 sec
Definition: dldetect.cpp:44
#define DLDAllocatePool(size)
Definition: dldetect.h:25
ULONG MaxThreadCount
Maximum supported number of threads (initialized by DLDInit())
Definition: dldetect.cpp:39
PTHREAD_STRUCT DLDThreadTable
Waiters table.
Definition: dldetect.cpp:42
#define BrutePoint()
Definition: env_spec_w32.h:504
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
#define I64(x)
Definition: byte_order.h:110
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
struct _THREAD_STRUCT * PTHREAD_STRUCT
LONGLONG QuadPart
Definition: typedefs.h:112

Referenced by DriverEntry().

◆ DLDpAcquireResourceExclusiveLite()

VOID DLDpAcquireResourceExclusiveLite ( IN PERESOURCE  Resource,
IN ERESOURCE_THREAD  Thread,
IN KIRQL  oldIrql,
IN ULONG  BugCheckId,
IN ULONG  Line 
)

Definition at line 261 of file dldetect.cpp.

267  {
268  KIRQL oldIrql2;
269 
270  if (!(Resource->ExclusiveWaiters)) {
271 
272  KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
273  KeAcquireSpinLock(&Resource->SpinLock, &oldIrql2);
274 
275  // If ExclusiveWaiters Event not yet allocated allocate new one
276  if (!(Resource->ExclusiveWaiters)) {
279  }
280  KeReleaseSpinLock(&Resource->SpinLock, oldIrql2);
281  DLDAcquireExclusive(Resource,BugCheckId,Line);
282 
283  } else {
284  Resource->NumberOfExclusiveWaiters++;
285 
287 
288 
289  // Set WaitingResource for current thread
290  ThrdStruct->WaitingResource = Resource;
291  ThrdStruct->BugCheckId = BugCheckId;
292  ThrdStruct->Line = Line;
293 
294  KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
295 
296  DLDpWaitForResource(Resource,&(Resource->ExclusiveWaiters->Header),ThrdStruct);
297 
298  KeAcquireSpinLock(&Resource->SpinLock, &oldIrql);
299 
300  ThrdStruct->WaitingResource = NULL;
301  ThrdStruct->ThreadId = 0;
302  ThrdStruct->BugCheckId = 0;
303  ThrdStruct->Line = 0;
304  Resource->OwnerThreads[0].OwnerThread = Thread;
305 
306  KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
307  }
308 }
struct _KEVENT * PKEVENT
VOID DLDAcquireExclusive(PERESOURCE Resource, ULONG BugCheckId, ULONG Line)
Definition: dldetect.cpp:313
PERESOURCE WaitingResource
Definition: dldetect.h:60
ERESOURCE_THREAD ThreadId
Definition: dldetect.h:59
ULONG Line
Definition: dldetect.h:62
PTHREAD_STRUCT DLDAllocFindThread(ULONG ThreadId)
Definition: dldetect.cpp:70
UCHAR KIRQL
Definition: env_spec_w32.h:591
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:848
smooth NULL
Definition: ftsmooth.c:416
#define RESOURCE_EVENT_TAG
Resource event (ExclusiveWaiters)
Definition: dldetect.cpp:29
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
Definition: ncftp.h:79
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
VOID DLDpWaitForResource(IN PERESOURCE Resource, IN DISPATCHER_HEADER *DispatcherObject, IN PTHREAD_STRUCT ThrdStruct)
Definition: dldetect.cpp:225
ULONG BugCheckId
Definition: dldetect.h:61
struct Line Line

Referenced by DLDAcquireExclusive().

◆ DLDpFindCurrentThread()

POWNER_ENTRY DLDpFindCurrentThread ( IN PERESOURCE  Resource,
IN ERESOURCE_THREAD  Thread 
)

Definition at line 345 of file dldetect.cpp.

348  {
349 
350  if (Resource->OwnerThreads[0].OwnerThread == Thread) return &(Resource->OwnerThreads[0]);
351  if (Resource->OwnerThreads[1].OwnerThread == Thread) return &(Resource->OwnerThreads[1]);
352 
353  POWNER_ENTRY LastEntry, CurrentEntry, FirstEmptyEntry = NULL;
354  if (!(Resource->OwnerThreads[1].OwnerThread)) FirstEmptyEntry = &(Resource->OwnerThreads[1]);
355 
356  CurrentEntry = Resource->OwnerTable;
357  LastEntry = &(Resource->OwnerTable[Resource->OwnerThreads[0].TableSize]);
358 
359  while (CurrentEntry != LastEntry) {
360  if (CurrentEntry->OwnerThread == Thread) {
361  PCHAR CurrentThread = (PCHAR)PsGetCurrentThread();
362  *((PULONG)(CurrentThread + 0x136)) = CurrentEntry - Resource->OwnerTable;
363  return CurrentEntry;
364  }
365  if (!(CurrentEntry->OwnerThread)) {
366  FirstEmptyEntry = CurrentEntry;
367  }
368  CurrentEntry++;
369  }
370  if (FirstEmptyEntry) {
371  PCHAR CurrentThread = (PCHAR)PsGetCurrentThread();
372  *((PULONG)(CurrentThread + 0x136)) = FirstEmptyEntry - Resource->OwnerTable;
373  return FirstEmptyEntry;
374  } else {
375  // Grow OwnerTable
376 
377 
378  USHORT OldSize = Resource->OwnerThreads[0].TableSize;
379  USHORT NewSize = 3;
380  if (OldSize) NewSize = OldSize + 4;
382  RtlZeroMemory(NewEntry,sizeof(OWNER_ENTRY)*NewSize);
383  if (Resource->OwnerTable) {
384  RtlMoveMemory(NewEntry,Resource->OwnerTable,sizeof(OWNER_ENTRY)*OldSize);
385  ExFreePool(Resource->OwnerTable);
386  }
387  Resource->OwnerTable = NewEntry;
388 
389  PCHAR CurrentThread = (PCHAR)PsGetCurrentThread();
390  *((PULONG)(CurrentThread + 0x136)) = OldSize;
391  Resource->OwnerThreads[0].TableSize = NewSize;
392 
393  return &(NewEntry[OldSize]);
394  }
395 }
signed char * PCHAR
Definition: retypes.h:7
Definition: extypes.h:210
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:848
smooth NULL
Definition: ftsmooth.c:416
#define RESOURCE_TABLE_TAG
Resource owner table (OwnerTable)
Definition: dldetect.cpp:33
#define PCHAR
Definition: match.c:90
struct _OWNER_ENTRY * POWNER_ENTRY
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
unsigned short USHORT
Definition: pedump.c:61
unsigned int * PULONG
Definition: retypes.h:1
ERESOURCE_THREAD OwnerThread
Definition: extypes.h:211
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by DLDAcquireShared().

◆ DLDProcessResource()

BOOLEAN DLDProcessResource ( PERESOURCE  Resource,
PTHREAD_STRUCT  ThrdStruct,
ULONG  RecLevel 
)

TRUE Indicates deadlock.

Definition at line 171 of file dldetect.cpp.

174 {
175  if (RecLevel <= 0) {
176  BrutePoint();
177  return FALSE;
178  }
179 
180 
181  // If resource is free, just return. Not possible, but we must check.
182  if (!Resource->ActiveCount) {
183  return FALSE;
184  }
185 
186  PTHREAD_STRUCT ThreadOwner;
187 
188 
189  if (Resource->Flag & ResourceOwnedExclusive || (Resource->OwnerThreads[1].OwnerCount == 1)) {
190 
191  // If only one owner
192 
193  // Find thread owning this resource
194  if (Resource->Flag & ResourceOwnedExclusive) {
195  ThreadOwner = DLDFindThread(Resource->OwnerThreads[0].OwnerThread);
196  } else {
197  ThreadOwner = DLDFindThread(Resource->OwnerThreads[1].OwnerThread);
198  }
199 
200  BOOLEAN Result = FALSE;
201  if (ThreadOwner) {
202  Result = DLDProcessThread(ThreadOwner, ThrdStruct, Resource,RecLevel-1);
203  }
204  return Result;
205  } else {
206  // Many owners
207  int i;
208  for (i=0; i<Resource->OwnerThreads[0].TableSize; i++) {
209  if (Resource->OwnerTable[i].OwnerThread) {
210 
211  ThreadOwner = DLDFindThread(Resource->OwnerTable[i].OwnerThread);
212  if (ThreadOwner && DLDProcessThread(ThreadOwner, ThrdStruct, Resource,RecLevel-1)) {
213 
214  return TRUE;
215  }
216  }
217  }
218  }
219 
220  return FALSE;
221 }
#define TRUE
Definition: types.h:120
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:848
unsigned char BOOLEAN
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
#define BrutePoint()
Definition: env_spec_w32.h:504
PTHREAD_STRUCT DLDFindThread(ULONG ThreadId)
Definition: dldetect.cpp:100
BOOLEAN DLDProcessThread(PTHREAD_STRUCT ThrdOwner, PTHREAD_STRUCT ThrdStruct, PERESOURCE Resource, ULONG RecLevel)
TRUE Indicates deadlock.
Definition: dldetect.cpp:123
#define ResourceOwnedExclusive
Definition: dldetect.h:32

Referenced by DLDProcessThread(), and DLDpWaitForResource().

◆ DLDProcessThread()

BOOLEAN DLDProcessThread ( PTHREAD_STRUCT  ThrdOwner,
PTHREAD_STRUCT  ThrdStruct,
PERESOURCE  Resource,
ULONG  RecLevel 
)

TRUE Indicates deadlock.

Definition at line 123 of file dldetect.cpp.

126  {
127 
128  if (ThrdOwner == ThrdStruct) {
129  // ERESOURCE wait cycle. Deadlock detected.
130  UDFPrint(("DLD: *********DEADLOCK DETECTED*********\n"));
131  UDFPrint(("Thread %x holding resource %x\n",ThrdOwner->ThreadId,Resource));
132  return TRUE;
133  }
134 
135  for (int i=RecLevel+1;i<DLD_MAX_REC_LEVEL;i++) {
136  if (DLDThreadAcquireChain[i].Thread->ThreadId == ThrdOwner->ThreadId) {
137  // ERESOURCE wait cycle. Deadlock detected.
138  UDFPrint(("DLD: *********DEADLOCK DETECTED*********\n"));
139  UDFPrint(("Thread %x holding resource %x\n",ThrdOwner->ThreadId,Resource));
140  for (int j=RecLevel+1;j<=i;j++) {
141  UDFPrint((" awaited by thread %x at (BugCheckId:%x:Line:%d) holding resource %x\n",
142  DLDThreadAcquireChain[i].Thread->ThreadId,
145  Resource));
146  }
147  BrutePoint();
148  return FALSE;
149  }
150  }
151  DLDThreadAcquireChain[RecLevel].Thread = ThrdOwner;
153 
154  // Find resource, awaited by thread
155  if (ThrdOwner->WaitingResource) {
156  if (DLDProcessResource(ThrdOwner->WaitingResource, ThrdStruct,RecLevel)) {
157  UDFPrint((" awaited by thread %x at (BugCheckId:%x:Line:%d) holding resource %x\n",
158  ThrdOwner->ThreadId,
159  ThrdOwner->BugCheckId,
160  ThrdOwner->Line,
161  Resource));
162  return TRUE;
163  }
164  }
165 
166  return FALSE;
167 }
#define UDFPrint(Args)
Definition: udffs.h:225
#define TRUE
Definition: types.h:120
#define DLD_MAX_REC_LEVEL
Maxmum recurse level while exploring thread-resource aquisition graf.
Definition: dldetect.cpp:36
PERESOURCE WaitingResource
Definition: dldetect.h:60
ERESOURCE_THREAD ThreadId
Definition: dldetect.h:59
ULONG Line
Definition: dldetect.h:62
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:848
BOOLEAN DLDProcessResource(PERESOURCE Resource, PTHREAD_STRUCT ThrdStruct, ULONG RecLevel)
TRUE Indicates deadlock.
Definition: dldetect.cpp:171
PTHREAD_STRUCT Thread
Definition: dldetect.h:67
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define BrutePoint()
Definition: env_spec_w32.h:504
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
THREAD_REC_BLOCK DLDThreadAcquireChain[DLD_MAX_REC_LEVEL]
Definition: dldetect.cpp:48
PERESOURCE HoldingResource
Definition: dldetect.h:68
ULONG BugCheckId
Definition: dldetect.h:61

Referenced by DLDProcessResource().

◆ DLDpWaitForResource()

VOID DLDpWaitForResource ( IN PERESOURCE  Resource,
IN DISPATCHER_HEADER DispatcherObject,
IN PTHREAD_STRUCT  ThrdStruct 
)

Definition at line 225 of file dldetect.cpp.

229  {
230  KIRQL oldIrql;
231  ULONG ResourceWaitCount = 0;
232 
233  Resource->ContentionCount++;
234 
236  KeAcquireSpinLock(&Resource->SpinLock, &oldIrql);
237  if (++ResourceWaitCount>DLDpResourceTimeoutCount) {
238  // May be deadlock?
239  ResourceWaitCount = 0;
240 
241  if (DLDProcessResource(Resource, ThrdStruct,DLD_MAX_REC_LEVEL)) {
242  UDFPrint((" which thread %x has tried to acquire at (BugCheckId:%x:Line:%d)\n",
243  ThrdStruct->ThreadId,
244  ThrdStruct->BugCheckId,
245  ThrdStruct->Line
246  ));
247  BrutePoint();
248  }
249  }
250  // Priority boosts
251  // .....
252  // End of priority boosts
253  KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
254  }
255 
256 }
#define UDFPrint(Args)
Definition: udffs.h:225
#define DLD_MAX_REC_LEVEL
Maxmum recurse level while exploring thread-resource aquisition graf.
Definition: dldetect.cpp:36
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
ULONG DLDpResourceTimeoutCount
8 sec
Definition: dldetect.cpp:46
LARGE_INTEGER DLDpTimeout
4 sec
Definition: dldetect.cpp:44
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
UCHAR KIRQL
Definition: env_spec_w32.h:591
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:848
BOOLEAN DLDProcessResource(PERESOURCE Resource, PTHREAD_STRUCT ThrdStruct, ULONG RecLevel)
TRUE Indicates deadlock.
Definition: dldetect.cpp:171
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define BrutePoint()
Definition: env_spec_w32.h:504
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
unsigned int ULONG
Definition: retypes.h:1

Referenced by DLDAcquireShared(), and DLDpAcquireResourceExclusiveLite().

Variable Documentation

◆ DLDpResourceTimeoutCount

ULONG DLDpResourceTimeoutCount = 0x2

8 sec

Definition at line 46 of file dldetect.cpp.

Referenced by DLDpWaitForResource().

◆ DLDpTimeout

LARGE_INTEGER DLDpTimeout

4 sec

Definition at line 44 of file dldetect.cpp.

Referenced by DLDInit(), and DLDpWaitForResource().

◆ DLDThreadAcquireChain

THREAD_REC_BLOCK DLDThreadAcquireChain[DLD_MAX_REC_LEVEL]

Definition at line 48 of file dldetect.cpp.

Referenced by DLDProcessThread().

◆ DLDThreadTable

PTHREAD_STRUCT DLDThreadTable

Waiters table.

Definition at line 42 of file dldetect.cpp.

Referenced by DLDAllocFindThread(), DLDFindThread(), DLDFree(), and DLDInit().

◆ MaxThreadCount

ULONG MaxThreadCount = 0

Maximum supported number of threads (initialized by DLDInit())

Definition at line 39 of file dldetect.cpp.

Referenced by DLDAllocFindThread(), DLDFindThread(), and DLDInit().