原始碼賞析
小實驗
/**
這個函式做了兩件事情:
1 : 註冊hub驅動
2 : 建立名為"khubd"的守護執行緒,它的作用是檢測hub的狀態變化。
*/int usb_hub_init(void)
; */
if (usb_register(&hub_driver) < 0)
/**建立了乙個守護程序,用於監視hub的狀態。
這個守護程序 在後面我們會看到 它會在urb的完成函式hub_irq()->kick_khubd()中被喚醒。
它在什麼時候被睡眠?
怎麼被喚醒的?
我們往下面看
kthread_run()這個函式底層呼叫了kthread_create()函式,kthread_create()會喚醒睡眠的2號
程序kthreadd 來建立核心執行緒,請見我以前的博文的賞析
*/khubd_task = kthread_run(hub_thread,null,"khubd");
/**如果khubd成功建立,那麼就返回了。
*/if(!is_err(khubd_task))
/**以下**是 核心執行緒"khubd"建立不成功過的時候執行的
解除安裝hub驅動
*/usb_deregister(&hub_driver);
printk(kern_err "%s: can't start khubd\n", usbcore_name);
return -1;
}static
int hub_thread(void * __unnsed)
.....
}由上面**可以知道,
如果hub_event_list為空,那麼就會執行下面的wait_event_freezable()進行睡眠。
hub_event_list的初始值就是空,那麼就直接break了,返回hub_thread,然後就睡眠,等待事件的到來。
修改了核心**,這裡實驗驗證了一下,核心列印的log:
usbcore: registered new inte***ce driver usbfs
usbcore: registered new inte***ce driver hub
list_empty----**: 1 新增的code
usbcore: registered new device driver usb
如果hub_event_list不為空,就會進行進行usb的列舉,這一部分 我們放在下面欣賞
*/hub_events();
/**看看它的condition :
!list_empty(&hub_event_list) ||kthread_should_stop()
只要接收到stop停止訊號或者 hub_event_list為空,那麼就會睡眠
在下面的函式kick_khubd()中,是通過list_add_tail(&hub->event_list, &hub_event_list)
來喚醒的。
它的底層呼叫到了 __wait_event_interruptible()函式,
這個函式會呼叫set_current_state(task_interruptible);將執行緒的狀態設定成task_interruptible
然後如果沒有訊號需要處理,就呼叫schedule()讓程序一直休眠直到條件滿足為止。
這個函式的分析請見我以前的博文。
*/wait_event_freezable(khubd_wait,!list_empty(&hub_event_list) ||kthread_should_stop());
}while (!kthread_should_stop() || !list_empty(&hub_event_list));
}/**
hub正常工作後,usb主機控制器就會定時的詢問hub,
如果hub埠上有usb裝置的插入、拔出的時候,hub就會把埠的狀態變化告訴usb主機控制器
這是通過向usb主機控制器傳送urb請求(當然是中斷urb了)來實現的。當usb主機控制器處理完成這個urb後,
那麼urb的完成函式hub_irq()就被呼叫了,
*/static
void hub_irq(struct urb *urb)
填充中斷型別的urb,完成函式:hub_irq().
usb_fill_int_urb(hub->urb, hdev, pipe, *hub->buffer, maxp, hub_irq,
hub, endpoint->binterval);
.....}*/
int status = urb->status;
unsigned i;
unsigned long bits;
.....
/*呼叫了這個函式。它會喚醒前面睡眠的執行緒的
js中new之後發生了什麼
functionfn var newfn newfn console.log newfn.a 1 在new之後究竟發生了什麼呢?var newfn newfn.proto fn.prototype fn.call newfn 最後返回乙個新的物件 接下來說一下原型鏈 首先明確的是函式有prototy...
位址列回車之後發生了什麼
一 瀏覽器會傳送乙個get請求,該請求會被 到dns伺服器,由dns伺服器解析網域名稱,然後再 到相應的ip位址對應的伺服器。二 在伺服器端由apache這樣的web server來接收請求,並進行相應的處理,然後響應結果給客戶端瀏覽器。三 瀏覽器接收響應的結果,並進行相應的語法檢查,如果有錯誤,可...
new Vue 發生了什麼
合併options 初始化生命週期 初始化事件 初始化渲染 觸發beforecreate鉤子 export function initstate vm component else true asrootdata if opts.computed initcomputed vm,opts.compu...