Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[kernel][mutex] fix bug of thread exit without releasing mutex & add error check log #9337

Merged
merged 3 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bsp/apm32/apm32f030r8-miniboard/rtconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
if os.getenv('RTT_EXEC_PATH'):
EXEC_PATH = os.getenv('RTT_EXEC_PATH')

BUILD = 'debug'
BUILD = 'release'

if PLATFORM == 'gcc':
# toolchains
Expand Down
2 changes: 1 addition & 1 deletion bsp/apm32/apm32f051r8-evalboard/rtconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
if os.getenv('RTT_EXEC_PATH'):
EXEC_PATH = os.getenv('RTT_EXEC_PATH')

BUILD = 'debug'
BUILD = 'release'

if PLATFORM == 'gcc':
# toolchains
Expand Down
2 changes: 1 addition & 1 deletion src/ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1349,7 +1349,7 @@ static rt_err_t _rt_mutex_take(rt_mutex_t mutex, rt_int32_t timeout, int suspend

if (mutex->owner == thread)
{
if(mutex->hold < RT_MUTEX_HOLD_MAX)
if (mutex->hold < RT_MUTEX_HOLD_MAX)
{
/* it's the same thread */
mutex->hold ++;
Expand Down
75 changes: 40 additions & 35 deletions src/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,44 @@ void rt_thread_resume_sethook(void (*hook)(rt_thread_t thread))
RT_OBJECT_HOOKLIST_DEFINE(rt_thread_inited);
#endif /* defined(RT_USING_HOOK) && defined(RT_HOOK_USING_FUNC_PTR) */

#ifdef RT_USING_MUTEX
static void _thread_detach_from_mutex(rt_thread_t thread)
{
rt_list_t *node;
rt_list_t *tmp_list;
struct rt_mutex *mutex;
rt_base_t level;

level = rt_spin_lock_irqsave(&thread->spinlock);

/* check if thread is waiting on a mutex */
if ((thread->pending_object) &&
(rt_object_get_type(thread->pending_object) == RT_Object_Class_Mutex))
{
/* remove it from its waiting list */
struct rt_mutex *mutex = (struct rt_mutex*)thread->pending_object;
rt_mutex_drop_thread(mutex, thread);
thread->pending_object = RT_NULL;
}

/* free taken mutex after detaching from waiting, so we don't lost mutex just got */
rt_list_for_each_safe(node, tmp_list, &(thread->taken_object_list))
{
mutex = rt_list_entry(node, struct rt_mutex, taken_list);
LOG_D("Thread [%s] exits while holding mutex [%s].\n", thread->parent.name, mutex->parent.parent.name);
/* recursively take */
mutex->hold = 1;
rt_mutex_release(mutex);
}

rt_spin_unlock_irqrestore(&thread->spinlock, level);
}

#else

static void _thread_detach_from_mutex(rt_thread_t thread) {}
#endif

static void _thread_exit(void)
{
struct rt_thread *thread;
Expand All @@ -88,6 +126,8 @@ static void _thread_exit(void)

rt_thread_close(thread);

_thread_detach_from_mutex(thread);

/* insert to defunct thread list */
rt_thread_defunct_enqueue(thread);

Expand Down Expand Up @@ -133,41 +173,6 @@ static void _thread_timeout(void *parameter)
rt_sched_unlock_n_resched(slvl);
}

#ifdef RT_USING_MUTEX
static void _thread_detach_from_mutex(rt_thread_t thread)
{
rt_list_t *node;
rt_list_t *tmp_list;
struct rt_mutex *mutex;
rt_base_t level;

level = rt_spin_lock_irqsave(&thread->spinlock);

/* check if thread is waiting on a mutex */
if ((thread->pending_object) &&
(rt_object_get_type(thread->pending_object) == RT_Object_Class_Mutex))
{
/* remove it from its waiting list */
struct rt_mutex *mutex = (struct rt_mutex*)thread->pending_object;
rt_mutex_drop_thread(mutex, thread);
thread->pending_object = RT_NULL;
}

/* free taken mutex after detaching from waiting, so we don't lost mutex just got */
rt_list_for_each_safe(node, tmp_list, &(thread->taken_object_list))
{
mutex = rt_list_entry(node, struct rt_mutex, taken_list);
rt_mutex_release(mutex);
}

rt_spin_unlock_irqrestore(&thread->spinlock, level);
}

#else

static void _thread_detach_from_mutex(rt_thread_t thread) {}
#endif

static rt_err_t _thread_init(struct rt_thread *thread,
const char *name,
void (*entry)(void *parameter),
Expand Down
Loading