Skip to content

Commit 934179a

Browse files
committed
Remove concept of ownership and abandonment and other vistigial components of mutexes from the CoreCLR PAL.
1 parent 00ac1f8 commit 934179a

File tree

19 files changed

+78
-1047
lines changed

19 files changed

+78
-1047
lines changed

src/coreclr/pal/inc/pal.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -847,8 +847,6 @@ GetExitCodeProcess(
847847

848848
#define MAXIMUM_WAIT_OBJECTS 64
849849
#define WAIT_OBJECT_0 0
850-
#define WAIT_ABANDONED 0x00000080
851-
#define WAIT_ABANDONED_0 0x00000080
852850
#define WAIT_TIMEOUT 258
853851
#define WAIT_FAILED ((DWORD)0xFFFFFFFF)
854852

src/coreclr/pal/src/config.h.in

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,6 @@
104104
#cmakedefine PAL_PTRACE(cmd, pid, addr, data) @PAL_PTRACE@
105105
#cmakedefine01 SYNCHMGR_SUSPENSION_SAFE_CONDITION_SIGNALING
106106
#cmakedefine01 ERROR_FUNC_FOR_GLOB_HAS_FIXED_PARAMS
107-
#cmakedefine01 HAVE_FULLY_FEATURED_PTHREAD_MUTEXES
108-
#cmakedefine01 HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES
109107
#cmakedefine BSD_REGS_STYLE(reg, RR, rr) @BSD_REGS_STYLE@
110108
#cmakedefine01 HAVE_SCHED_OTHER_ASSIGNABLE
111109
#cmakedefine01 SET_SCHEDPARAM_NEEDS_PRIVS

src/coreclr/pal/src/configure.cmake

Lines changed: 0 additions & 224 deletions
Original file line numberDiff line numberDiff line change
@@ -665,230 +665,6 @@ int main(int argc, char **argv)
665665
return 0;
666666
}" HAVE_PR_SET_PTRACER)
667667

668-
set(CMAKE_REQUIRED_LIBRARIES pthread)
669-
check_cxx_source_compiles("
670-
#include <errno.h>
671-
#include <pthread.h>
672-
#include <time.h>
673-
674-
int main()
675-
{
676-
pthread_mutexattr_t mutexAttributes;
677-
pthread_mutexattr_init(&mutexAttributes);
678-
pthread_mutexattr_setpshared(&mutexAttributes, PTHREAD_PROCESS_SHARED);
679-
pthread_mutexattr_settype(&mutexAttributes, PTHREAD_MUTEX_RECURSIVE);
680-
pthread_mutexattr_setrobust(&mutexAttributes, PTHREAD_MUTEX_ROBUST);
681-
682-
pthread_mutex_t mutex;
683-
pthread_mutex_init(&mutex, &mutexAttributes);
684-
685-
pthread_mutexattr_destroy(&mutexAttributes);
686-
687-
struct timespec timeoutTime;
688-
timeoutTime.tv_sec = 1; // not the right way to specify absolute time, but just checking availability of timed lock
689-
timeoutTime.tv_nsec = 0;
690-
pthread_mutex_timedlock(&mutex, &timeoutTime);
691-
pthread_mutex_consistent(&mutex);
692-
693-
pthread_mutex_destroy(&mutex);
694-
695-
int error = EOWNERDEAD;
696-
error = ENOTRECOVERABLE;
697-
error = ETIMEDOUT;
698-
error = 0;
699-
return error;
700-
}" HAVE_FULLY_FEATURED_PTHREAD_MUTEXES)
701-
set(CMAKE_REQUIRED_LIBRARIES)
702-
703-
if(NOT CLR_CMAKE_HOST_ARCH_ARM AND NOT CLR_CMAKE_HOST_ARCH_ARM64)
704-
set(CMAKE_REQUIRED_LIBRARIES pthread)
705-
check_cxx_source_runs("
706-
// This test case verifies the pthread process-shared robust mutex's cross-process abandon detection. The parent process starts
707-
// a child process that locks the mutex, the process process then waits to acquire the lock, and the child process abandons the
708-
// mutex by exiting the process while holding the lock. The parent process should then be released from its wait, be assigned
709-
// ownership of the lock, and be notified that the mutex was abandoned.
710-
711-
#include <sys/mman.h>
712-
#include <sys/time.h>
713-
714-
#include <errno.h>
715-
#include <pthread.h>
716-
#include <stdio.h>
717-
#include <unistd.h>
718-
719-
#include <new>
720-
using namespace std;
721-
722-
struct Shm
723-
{
724-
pthread_mutex_t syncMutex;
725-
pthread_cond_t syncCondition;
726-
pthread_mutex_t robustMutex;
727-
int conditionValue;
728-
729-
Shm() : conditionValue(0)
730-
{
731-
}
732-
} *shm;
733-
734-
int GetFailTimeoutTime(struct timespec *timeoutTimeRef)
735-
{
736-
int getTimeResult = clock_gettime(CLOCK_REALTIME, timeoutTimeRef);
737-
if (getTimeResult != 0)
738-
{
739-
struct timeval tv;
740-
getTimeResult = gettimeofday(&tv, NULL);
741-
if (getTimeResult != 0)
742-
return 1;
743-
timeoutTimeRef->tv_sec = tv.tv_sec;
744-
timeoutTimeRef->tv_nsec = tv.tv_usec * 1000;
745-
}
746-
timeoutTimeRef->tv_sec += 30;
747-
return 0;
748-
}
749-
750-
int WaitForConditionValue(int desiredConditionValue)
751-
{
752-
struct timespec timeoutTime;
753-
if (GetFailTimeoutTime(&timeoutTime) != 0)
754-
return 1;
755-
if (pthread_mutex_timedlock(&shm->syncMutex, &timeoutTime) != 0)
756-
return 1;
757-
758-
if (shm->conditionValue != desiredConditionValue)
759-
{
760-
if (GetFailTimeoutTime(&timeoutTime) != 0)
761-
return 1;
762-
if (pthread_cond_timedwait(&shm->syncCondition, &shm->syncMutex, &timeoutTime) != 0)
763-
return 1;
764-
if (shm->conditionValue != desiredConditionValue)
765-
return 1;
766-
}
767-
768-
if (pthread_mutex_unlock(&shm->syncMutex) != 0)
769-
return 1;
770-
return 0;
771-
}
772-
773-
int SetConditionValue(int newConditionValue)
774-
{
775-
struct timespec timeoutTime;
776-
if (GetFailTimeoutTime(&timeoutTime) != 0)
777-
return 1;
778-
if (pthread_mutex_timedlock(&shm->syncMutex, &timeoutTime) != 0)
779-
return 1;
780-
781-
shm->conditionValue = newConditionValue;
782-
if (pthread_cond_signal(&shm->syncCondition) != 0)
783-
return 1;
784-
785-
if (pthread_mutex_unlock(&shm->syncMutex) != 0)
786-
return 1;
787-
return 0;
788-
}
789-
790-
void DoTest_Child();
791-
792-
int DoTest()
793-
{
794-
// Map some shared memory
795-
void *shmBuffer = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
796-
if (shmBuffer == MAP_FAILED)
797-
return 1;
798-
shm = new(shmBuffer) Shm;
799-
800-
// Create sync mutex
801-
pthread_mutexattr_t syncMutexAttributes;
802-
if (pthread_mutexattr_init(&syncMutexAttributes) != 0)
803-
return 1;
804-
if (pthread_mutexattr_setpshared(&syncMutexAttributes, PTHREAD_PROCESS_SHARED) != 0)
805-
return 1;
806-
if (pthread_mutex_init(&shm->syncMutex, &syncMutexAttributes) != 0)
807-
return 1;
808-
if (pthread_mutexattr_destroy(&syncMutexAttributes) != 0)
809-
return 1;
810-
811-
// Create sync condition
812-
pthread_condattr_t syncConditionAttributes;
813-
if (pthread_condattr_init(&syncConditionAttributes) != 0)
814-
return 1;
815-
if (pthread_condattr_setpshared(&syncConditionAttributes, PTHREAD_PROCESS_SHARED) != 0)
816-
return 1;
817-
if (pthread_cond_init(&shm->syncCondition, &syncConditionAttributes) != 0)
818-
return 1;
819-
if (pthread_condattr_destroy(&syncConditionAttributes) != 0)
820-
return 1;
821-
822-
// Create the robust mutex that will be tested
823-
pthread_mutexattr_t robustMutexAttributes;
824-
if (pthread_mutexattr_init(&robustMutexAttributes) != 0)
825-
return 1;
826-
if (pthread_mutexattr_setpshared(&robustMutexAttributes, PTHREAD_PROCESS_SHARED) != 0)
827-
return 1;
828-
if (pthread_mutexattr_setrobust(&robustMutexAttributes, PTHREAD_MUTEX_ROBUST) != 0)
829-
return 1;
830-
if (pthread_mutex_init(&shm->robustMutex, &robustMutexAttributes) != 0)
831-
return 1;
832-
if (pthread_mutexattr_destroy(&robustMutexAttributes) != 0)
833-
return 1;
834-
835-
// Start child test process
836-
int error = fork();
837-
if (error == -1)
838-
return 1;
839-
if (error == 0)
840-
{
841-
DoTest_Child();
842-
return -1;
843-
}
844-
845-
// Wait for child to take a lock
846-
WaitForConditionValue(1);
847-
848-
// Wait to try to take a lock. Meanwhile, child abandons the robust mutex.
849-
struct timespec timeoutTime;
850-
if (GetFailTimeoutTime(&timeoutTime) != 0)
851-
return 1;
852-
error = pthread_mutex_timedlock(&shm->robustMutex, &timeoutTime);
853-
if (error != EOWNERDEAD) // expect to be notified that the robust mutex was abandoned
854-
return 1;
855-
if (pthread_mutex_consistent(&shm->robustMutex) != 0)
856-
return 1;
857-
858-
if (pthread_mutex_unlock(&shm->robustMutex) != 0)
859-
return 1;
860-
if (pthread_mutex_destroy(&shm->robustMutex) != 0)
861-
return 1;
862-
return 0;
863-
}
864-
865-
void DoTest_Child()
866-
{
867-
// Lock the robust mutex
868-
struct timespec timeoutTime;
869-
if (GetFailTimeoutTime(&timeoutTime) != 0)
870-
return;
871-
if (pthread_mutex_timedlock(&shm->robustMutex, &timeoutTime) != 0)
872-
return;
873-
874-
// Notify parent that robust mutex is locked
875-
if (SetConditionValue(1) != 0)
876-
return;
877-
878-
// Wait a short period to let the parent block on waiting for a lock
879-
sleep(1);
880-
881-
// Abandon the mutex by exiting the process while holding the lock. Parent's wait should be released by EOWNERDEAD.
882-
}
883-
884-
int main()
885-
{
886-
int result = DoTest();
887-
return result >= 0 ? result : 0;
888-
}" HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES)
889-
set(CMAKE_REQUIRED_LIBRARIES)
890-
endif()
891-
892668
if(CLR_CMAKE_TARGET_APPLE)
893669
set(HAVE__NSGETENVIRON 1)
894670
set(DEADLOCK_WHEN_THREAD_IS_SUSPENDED_WHILE_BLOCKED_ON_MUTEX 1)

src/coreclr/pal/src/file/file.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,7 @@ CObjectType CorUnix::otFile(
7575
CFileProcessLocalDataCleanupRoutine,
7676
CObjectType::UnwaitableObject,
7777
CObjectType::SignalingNotApplicable,
78-
CObjectType::ThreadReleaseNotApplicable,
79-
CObjectType::OwnershipNotApplicable
78+
CObjectType::ThreadReleaseNotApplicable
8079
);
8180

8281
CAllowedObjectTypes CorUnix::aotFile(otiFile);

src/coreclr/pal/src/include/pal/corunix.hpp

Lines changed: 3 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,6 @@ namespace CorUnix
204204
// Must be ThreadReleaseHasNoSideEffects if eSignalingSemantics is
205205
// SingleTransitionObject
206206
//
207-
// * eOwnershipSemantics: OwnershipTracked only for mutexes, for which the
208-
// previous two items must also ObjectCanBeUnsignaled and
209-
// ThreadReleaseAltersSignalCount.
210-
//
211207

212208
class CObjectType
213209
{
@@ -232,13 +228,6 @@ namespace CorUnix
232228
ThreadReleaseNotApplicable
233229
};
234230

235-
enum OwnershipSemantics
236-
{
237-
OwnershipTracked,
238-
NoOwner,
239-
OwnershipNotApplicable
240-
};
241-
242231
private:
243232

244233
//
@@ -259,7 +248,6 @@ namespace CorUnix
259248
SynchronizationSupport m_eSynchronizationSupport;
260249
SignalingSemantics m_eSignalingSemantics;
261250
ThreadReleaseSemantics m_eThreadReleaseSemantics;
262-
OwnershipSemantics m_eOwnershipSemantics;
263251

264252
public:
265253

@@ -273,8 +261,7 @@ namespace CorUnix
273261
OBJECT_PROCESS_LOCAL_DATA_CLEANUP_ROUTINE pProcessLocalDataCleanupRoutine,
274262
SynchronizationSupport eSynchronizationSupport,
275263
SignalingSemantics eSignalingSemantics,
276-
ThreadReleaseSemantics eThreadReleaseSemantics,
277-
OwnershipSemantics eOwnershipSemantics
264+
ThreadReleaseSemantics eThreadReleaseSemantics
278265
)
279266
:
280267
m_eTypeId(eTypeId),
@@ -286,8 +273,7 @@ namespace CorUnix
286273
m_pProcessLocalDataCleanupRoutine(pProcessLocalDataCleanupRoutine),
287274
m_eSynchronizationSupport(eSynchronizationSupport),
288275
m_eSignalingSemantics(eSignalingSemantics),
289-
m_eThreadReleaseSemantics(eThreadReleaseSemantics),
290-
m_eOwnershipSemantics(eOwnershipSemantics)
276+
m_eThreadReleaseSemantics(eThreadReleaseSemantics)
291277
{
292278
s_rgotIdMapping[eTypeId] = this;
293279
};
@@ -398,14 +384,6 @@ namespace CorUnix
398384
{
399385
return m_eThreadReleaseSemantics;
400386
};
401-
402-
OwnershipSemantics
403-
GetOwnershipSemantics(
404-
void
405-
)
406-
{
407-
return m_eOwnershipSemantics;
408-
};
409387
};
410388

411389
class CAllowedObjectTypes
@@ -529,36 +507,6 @@ namespace CorUnix
529507
LONG lAmountToDecrement
530508
) = 0;
531509

532-
//
533-
// The following two routines may only be used for object types
534-
// where eOwnershipSemantics is OwnershipTracked (i.e., mutexes).
535-
//
536-
537-
//
538-
// SetOwner is intended to be used in the implementation of
539-
// CreateMutex when bInitialOwner is TRUE. It must be called
540-
// before the new object instance is registered with the
541-
// handle manager. Any other call to this method is an error.
542-
//
543-
544-
virtual
545-
PAL_ERROR
546-
SetOwner(
547-
CPalThread *pNewOwningThread
548-
) = 0;
549-
550-
//
551-
// DecrementOwnershipCount returns an error if the object
552-
// is unowned, or if the thread this controller is bound to
553-
// is not the owner of the object.
554-
//
555-
556-
virtual
557-
PAL_ERROR
558-
DecrementOwnershipCount(
559-
void
560-
) = 0;
561-
562510
virtual
563511
void
564512
ReleaseController(
@@ -604,8 +552,7 @@ namespace CorUnix
604552
virtual
605553
PAL_ERROR
606554
CanThreadWaitWithoutBlocking(
607-
bool *pfCanWaitWithoutBlocking, // OUT
608-
bool *pfAbandoned
555+
bool *pfCanWaitWithoutBlocking // OUT
609556
) = 0;
610557

611558
virtual
@@ -915,7 +862,6 @@ namespace CorUnix
915862
{
916863
WaitSucceeded,
917864
Alerted,
918-
MutexAbandoned,
919865
WaitTimeout,
920866
WaitFailed
921867
};
@@ -946,13 +892,6 @@ namespace CorUnix
946892
DWORD *pdwSignaledObject // OUT
947893
) = 0;
948894

949-
virtual
950-
PAL_ERROR
951-
AbandonObjectsOwnedByThread(
952-
CPalThread *pCallingThread,
953-
CPalThread *pTargetThread
954-
) = 0;
955-
956895
virtual
957896
PAL_ERROR
958897
QueueUserAPC(

0 commit comments

Comments
 (0)