From 87de18d1ec088536a284cadda1d0b9cd48ff8550 Mon Sep 17 00:00:00 2001 From: hujun5 Date: Fri, 13 Dec 2024 11:21:49 +0800 Subject: [PATCH] pthread: remove enter_critical_section in pthread_mutex reason: We would like to replace the critical section with a small lock. Signed-off-by: hujun5 --- sched/pthread/CMakeLists.txt | 3 +- sched/pthread/Make.defs | 2 +- sched/pthread/pthread_mutex.c | 60 ++++++++++++++- sched/pthread/pthread_mutexinconsistent.c | 89 ----------------------- 4 files changed, 58 insertions(+), 96 deletions(-) delete mode 100644 sched/pthread/pthread_mutexinconsistent.c diff --git a/sched/pthread/CMakeLists.txt b/sched/pthread/CMakeLists.txt index 2ccf5d358f87d..6921bfe6f603e 100644 --- a/sched/pthread/CMakeLists.txt +++ b/sched/pthread/CMakeLists.txt @@ -46,8 +46,7 @@ if(NOT CONFIG_DISABLE_PTHREAD) pthread_setschedprio.c) if(NOT CONFIG_PTHREAD_MUTEX_UNSAFE) - list(APPEND SRCS pthread_mutex.c pthread_mutexconsistent.c - pthread_mutexinconsistent.c) + list(APPEND SRCS pthread_mutex.c pthread_mutexconsistent.c) endif() if(CONFIG_SMP) diff --git a/sched/pthread/Make.defs b/sched/pthread/Make.defs index bff1a88da1ae0..4a696068fa007 100644 --- a/sched/pthread/Make.defs +++ b/sched/pthread/Make.defs @@ -32,7 +32,7 @@ CSRCS += pthread_completejoin.c pthread_findjoininfo.c CSRCS += pthread_release.c pthread_setschedprio.c ifneq ($(CONFIG_PTHREAD_MUTEX_UNSAFE),y) -CSRCS += pthread_mutex.c pthread_mutexconsistent.c pthread_mutexinconsistent.c +CSRCS += pthread_mutex.c pthread_mutexconsistent.c endif ifeq ($(CONFIG_SMP),y) diff --git a/sched/pthread/pthread_mutex.c b/sched/pthread/pthread_mutex.c index 36eae29a0891a..0a5aef92da1dd 100644 --- a/sched/pthread/pthread_mutex.c +++ b/sched/pthread/pthread_mutex.c @@ -38,6 +38,12 @@ #include "sched/sched.h" #include "pthread/pthread.h" +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static spinlock_t g_mutex_lock = SP_UNLOCKED; + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -65,10 +71,10 @@ static void pthread_mutex_add(FAR struct pthread_mutex_s *mutex) /* Add the mutex to the list of mutexes held by this pthread */ - flags = enter_critical_section(); + flags = spin_lock_irqsave(&g_mutex_lock); mutex->flink = rtcb->mhead; rtcb->mhead = mutex; - leave_critical_section(flags); + spin_unlock_irqrestore(&g_mutex_lock, flags); } /**************************************************************************** @@ -92,7 +98,7 @@ static void pthread_mutex_remove(FAR struct pthread_mutex_s *mutex) FAR struct pthread_mutex_s *prev; irqstate_t flags; - flags = enter_critical_section(); + flags = spin_lock_irqsave(&g_mutex_lock); /* Remove the mutex from the list of mutexes held by this task */ @@ -118,7 +124,7 @@ static void pthread_mutex_remove(FAR struct pthread_mutex_s *mutex) } mutex->flink = NULL; - leave_critical_section(flags); + spin_unlock_irqrestore(&g_mutex_lock, flags); } /**************************************************************************** @@ -346,3 +352,49 @@ int pthread_mutex_restorelock(FAR struct pthread_mutex_s *mutex, return ret; } + +/**************************************************************************** + * Name: pthread_mutex_inconsistent + * + * Description: + * This function is called when a pthread is terminated via either + * pthread_exit() or pthread_cancel(). It will check for any mutexes + * held by exitting thread. It will mark them as inconsistent and + * then wake up the highest priority waiter for the mutex. That + * instance of pthread_mutex_lock() will then return EOWNERDEAD. + * + * Input Parameters: + * tcb -- a reference to the TCB of the exitting pthread. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void pthread_mutex_inconsistent(FAR struct tcb_s *tcb) +{ + FAR struct pthread_mutex_s *mutex; + irqstate_t flags; + + DEBUGASSERT(tcb != NULL); + + flags = spin_lock_irqsave(&g_mutex_lock); + + /* Remove and process each mutex held by this task */ + + while (tcb->mhead != NULL) + { + /* Remove the mutex from the TCB list */ + + mutex = tcb->mhead; + tcb->mhead = mutex->flink; + mutex->flink = NULL; + + /* Mark the mutex as INCONSISTENT and wake up any waiting thread */ + + mutex->flags |= _PTHREAD_MFLAGS_INCONSISTENT; + mutex_unlock(&mutex->mutex); + } + + spin_unlock_irqrestore(&g_mutex_lock, flags); +} diff --git a/sched/pthread/pthread_mutexinconsistent.c b/sched/pthread/pthread_mutexinconsistent.c deleted file mode 100644 index c946edfb2e152..0000000000000 --- a/sched/pthread/pthread_mutexinconsistent.c +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** - * sched/pthread/pthread_mutexinconsistent.c - * - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include - -#include -#include - -#include "pthread/pthread.h" - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: pthread_mutex_inconsistent - * - * Description: - * This function is called when a pthread is terminated via either - * pthread_exit() or pthread_cancel(). It will check for any mutexes - * held by exitting thread. It will mark them as inconsistent and - * then wake up the highest priority waiter for the mutex. That - * instance of pthread_mutex_lock() will then return EOWNERDEAD. - * - * Input Parameters: - * tcb -- a reference to the TCB of the exitting pthread. - * - * Returned Value: - * None. - * - ****************************************************************************/ - -void pthread_mutex_inconsistent(FAR struct tcb_s *tcb) -{ - FAR struct pthread_mutex_s *mutex; - irqstate_t flags; - - DEBUGASSERT(tcb != NULL); - - sched_lock(); - - /* Remove and process each mutex held by this task */ - - while (tcb->mhead != NULL) - { - /* Remove the mutex from the TCB list */ - - flags = enter_critical_section(); - mutex = tcb->mhead; - tcb->mhead = mutex->flink; - mutex->flink = NULL; - leave_critical_section(flags); - - /* Mark the mutex as INCONSISTENT and wake up any waiting thread */ - - mutex->flags |= _PTHREAD_MFLAGS_INCONSISTENT; - mutex_unlock(&mutex->mutex); - } - - sched_unlock(); -}