1. 程式人生 > 其它 >【問題排查】implicit declaration of function ‘interruptible_sleep_on‘處理

【問題排查】implicit declaration of function ‘interruptible_sleep_on‘處理

技術標籤:系統報錯及處理Linux 日常使用與開發linux問題排查git核心嵌入式

當前核心版本:3.18.y

原始碼對應的核心版本:2.6.37


問題

移植程式碼的時候報錯:

341:3: error: implicit declaration of function 'interruptible_sleep_on' [-Werror=implicit-function-declaration]
   interruptible_sleep_on (&tty->read_wait);
   ^

一樣是比較兩個版本的核心原始碼,發現interruptible_sleep_on這個函式在新的核心中已經被去掉了。

單純的百度搜索不到任何有用的資訊...還有沒有什麼辦法?


思路

這裡提供一個辦法,可以嘗試在官方的核心原始碼的git提交日誌中,搜尋一些有用的資訊。

Ps:這裡前提肯定是用git下載linux核心原始碼了,需要對git有一定的熟悉度。

附上linux原始碼官網:https://www.kernel.org/

【開發工具】【git】通過關鍵字搜尋對應的git提交日誌


分析

通過"git log --grep=interruptible_sleep_on"命令,找到git提交日誌,並查到相關資訊:

commit 76ae0536ddc0aa576f2aac11f0f82d0fd60b522c
Author: Arnd Bergmann <
[email protected]
> Date: Wed Feb 26 12:01:49 2014 +0100 parport: fix interruptible_sleep_on race The interruptible_sleep_on function is can still lead to the deadlock mentioned in the comment above the caller, and we want to remove it soon, so replace it now with the race-free wait_event_interruptible. Signed-off-by: Arnd Bergmann <
[email protected]
> Cc: Andrew Morton <[email protected]> Cc: Greg Kroah-Hartman <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>

根據提交日誌上的內容,明白了原因是interruptible_sleep_on函式仍然會導致死鎖,因此被刪除了,解決辦法是立即使用無競爭的wait_event_interruptible替換它。

對應的替換函式:

【include/linux/wait.h】
#define __wait_event_interruptible(wq, condition)			\
	___wait_event(wq, condition, TASK_INTERRUPTIBLE, 0, 0,		\
		      schedule())

/**
 * wait_event_interruptible - sleep until a condition gets true
 * @wq: the waitqueue to wait on
 * @condition: a C expression for the event to wait for
 *
 * The process is put to sleep (TASK_INTERRUPTIBLE) until the
 * @condition evaluates to true or a signal is received.
 * The @condition is checked each time the waitqueue @wq is woken up.
 *
 * wake_up() has to be called after changing any variable that could
 * change the result of the wait condition.
 *
 * The function will return -ERESTARTSYS if it was interrupted by a
 * signal and 0 if @condition evaluated to true.
 */
#define wait_event_interruptible(wq, condition)				\
({									\
	int __ret = 0;							\
	if (!(condition))						\
		__ret = __wait_event_interruptible(wq, condition);	\
	__ret;								\
})

再看看interruptible_sleep_on函式的定義,做一個比較:

void __sched interruptible_sleep_on(wait_queue_head_t *q)
{
	sleep_on_common(q, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);
}

Ps:新的wait_event_interruptible函式多了一個引數...就需要我們實際替換的時候,注意更多地方。


例項

講下我實際的程式碼中是如何替換的。

私有結構體中新增成員,對應condition。
	bool              write_done;
	wait_queue_head_t write_wait;

在wake_up_interruptible函式之前設定write_done:
	&trans->write_done = true;
	wake_up_interruptible (&trans->write_wait);
 
 在原先的interruptible_sleep_on函式處,替換為wait_event_interruptible:
     trans->write_done = false;
     wait_event_interruptible(&trans->write_wait, trans->write_done);

搞定~