更新系統統計數

2021-05-26 16:55:26 字數 4815 閱讀 4164

更新時間和日期

使用者程式從

xtime

變數中獲得當前時間和日期。核心必須周期性地更新該變數,才能使它的值保持相當的精確。

全域性時鐘中斷處理程式呼叫

update_times()

函式更新

xtime

變數的值,**如下:

voidupdate_times(void)

calc_load(ticks);

}我們回憶一下前面對時鐘中斷處理程式的描述,當執行該函式時,已經獲得用於寫操作

xtime_lock

順序鎖。

wall_jiffies

變數存放

xtime

變數最後更新的時間。觀察一下,

wall_jiffies

的值可以小於

jiffies-1,

因為一些定時器中斷會丟失,例如當中斷被禁止了很長一段時間,換句話說,核心不必每個時鐘節拍更新

xtime

變數。然而,最後不會有時鐘節拍丟失,因此,

xtime

最終存放正確的系統時間。對丟失的定時器中斷的檢查在

cur_timer

的mark_offset

中完成,參見前面的」單處理器系統上的計時結構」一節。

update_wall_time()

函式連續呼叫

update_wall_time_one_tick()

函式ticks

次,每次呼叫都給

xtime.tv_nsec

字段加上

1000000

。如果xtime.tv_nsec

的值大於

999999999

,那麼update_wall_time()

函式還會更新

xtime

的tv_sec

字段,如果系統發出

adjtimex()

系統呼叫,那麼函式可能會稍微調整

1000000

這個值使時鐘稍快或稍慢一點。

calc_load()

函式的描述請參見本章後面的」記錄系統負載」一節。

更新系統統計數

核心在與定時相關的其它任務中必須周期性地收集若干資料用於:

檢查執行程序的

cpu資源限制

更新與本地

cpu工作負載有關的統計數

計算平均系統負載

監管核心**

更新本地cpu

統計數

我們曾經提到過,單處理器系統上的全域性時鐘中斷處理程式或多處理器系統上的本地時鐘中斷處理程式呼叫

update_process_times()

函式來更新一些核心統計數。該函式執行以下步驟:

檢查當前程序執行了多長時間。當時鐘中斷發生時,根據當前程序執行在使用者態還是核心態,選擇呼叫

account_user_time()

還是account_system_time()

。每個函式基本上執行如下步驟。

a.更新當前程序描述符的

utime

欄位或stime

字段。在程序描述符中提供兩個被稱作

cutime

和cstime

的附加字段,分別用來統計子程序在使用者態和核心態下所經過的

cpu節拍數。由於效率的原因,

update_process_times()

並不更新這些字段,而只是當父程序詢問它的其中乙個子程序的狀態時才對其進行更新。

b.檢查是否已達到總的

cpu時限,如果是,向

current

程序傳送

sigxcpu

和sigkill

訊號,在第三章的」程序資源限制」一節中,講述了限制是如何被每個程序描述符的

signal->rlim[rlimit_cpu].rlim_cur

欄位所控制的。

c.呼叫

account_it_virt()

和account_it_prof()

來檢查程序定時器。

d.更新一些核心統計數,這些統計數存放在每

cpu變數

kstat

中。呼叫

raise_softirq()

來啟用本地

cpu上的

timer_softirq

任務佇列。

如果必須**一些老版本的,受

rcu保護的資料結構,那麼檢查本地

cpu是否經歷了靜止狀態並呼叫

tasklet_schedule()

來啟用本地

cpu的

rcu_tasklet

任務佇列。

呼叫scheduler_tick()

函式,該函式使當前程序的時間片計數器減

1,並檢查計數器是否已減到

0。我們將在第七章的」

scheduler_tick()

函式」一節深入討論這些操作。

記錄系統負載

任何unix

核心都要記錄系統進行了多少

cpu活動。這些統計資料由各種管理實用程式來使用。使用者輸入

uptime

命令後可以看到一些統計資料:如相對於最後

1分鐘,

5分鐘,

15分鐘的」平均負載」。在單處理器系統上,值

0意味著沒有活躍的程序在執行,而值

1意味著乙個單獨的程序

100%占有

cpu,值大於

1說明幾個執行著的程序共享

cpu。

update_times()

在每個節拍都要呼叫

calc_load()

函式來計算處於

task_running

或task_uninterruptible

狀態的程序數,並用這個資料更新平均系統負載。

監管核心**

linux

包含乙個被稱作

readprofiler

的最低要求的**監管器,

linux

開發者用其發現核心在核心態的什麼地方花費時間。監管器確定核心的」熱點」

----

執行最頻繁的核心**片段。確定核心」熱點」是非常重要的。因為這可以指出應當進一步優化的核心函式。

監管器基於非常簡單的蒙特卡洛演算法;在每次時鐘中斷發生時,核心確定該中斷是否發生在核心態;如果是,核心從堆疊取回中斷發生前的

eip暫存器的值。並用這個值揭示中斷發生前核心正在做什麼。最後,取樣資料積聚在」熱點」上。

profile_tick()

函式為**監管器採集資料。這個函式在單處理器系統上是由

do_timer_interrup()

呼叫的,在多處理器系統上是由

smp_local_timer_interrup()

函式呼叫的。

為了啟用**監管器,在

linux

核心啟動時必須傳遞字串引數」

profile=n」,這裡2

的n的次方表示要監管的**段的大小,採集的資料可以從

/proc/profile

檔案中讀取。可以通過修改這個檔案來重置計數器;在多處理器系統上,修改這個檔案還可以改變抽樣頻率。不過,核心開發者並不直接訪問

/proc/profile

檔案,而是用

readprofile

系統命令。

linux2.6

核心還包含了另乙個監管器,叫做

oprofile.

比如readprofile

,oprofile

除了更靈活,更可定製外,還能用於發現核心**,使用者態應用程式及系統庫中的熱點。當使用

ofrofile

時,profile_tick()

呼叫timer_notify()

函式來收集這個新監管器所使用的資料。

檢查非遮蔽中斷監視器

在多處理器系統上,

linux

為核心開發者還提供了另外一種功能;看門狗系統,這對於探測引起系統凍結的核心

bug可能相當有用。為了啟用這樣的看門狗,必須在核心啟動時傳遞

nmi_watchdog

引數。看門狗基於本地和

i/oapic

乙個巧妙的硬體特性;它們能在每個

cpu上產生週期性的

nmi中斷,因為

nmi中斷是不能用組合語言指令

cli遮蔽的,所以,即使禁止中斷,看門狗也能檢測到死鎖。

因而,一旦每個時鐘節拍到來,所有的

cpu,不管其正在做什麼,都開始執行

nmi中斷處理程式;該中斷處理程式又呼叫

do_nmi()

。這個函式獲得

cpu的邏輯號

n,然後檢查

irq_stat

陣列第n

項的apic_timer_irqs

字段。如果該

cpu欄位工作正常,那麼,第

n項的值必定不同於在前乙個

nmi中斷中讀出的值。當

cpu正常執行時,第n項的

apic_timer_irq

欄位就會被本地時鐘中斷處理程式增加,如果計數器沒有增加,說明本地時鐘中斷處理程式在整個時鐘節拍期間根本就沒有被執行,你可以想到,這可不是什麼好事。

當nmi

中斷處理程式檢測到乙個

cpu凍結時,就會敲響所有的鐘:它把引起恐慌的資訊記錄在系統日誌檔案中,轉儲該

cpu暫存器的內容和核心棧的內容。最後殺死當前程序,這就為核心開發者提供了發現錯誤的機會。

sysinfo 獲得系統統計資訊

sysinfo 系統呼叫會填充乙個有關系統統計資訊的結構。它唯一的引數是乙個指向 struct sysinfo 物件的指標。下列是 struct sysinfo 中一些比較有趣的域 uptime 從系統啟動開始已流逝的時間,以秒為單位。totalram 可用的物理記憶體總空間。freeram 空閒的...

linux 更新系統時間

1.ntpdate 命令更新時間 ntpdate asia.pool.ntp.org 2.date 命令更新時間 例 更新時間為 10年12月13日 date s 101213 更新時間為 14 20 00 date s 14 20 00 更新時間為 2010 12 13 14 26 date s ...

linux更新系統時間

檢查是否安裝過ntp rpm aq grep ntp 如果沒有裝用 yum install ntp 完成後 ntpdate time.windows.com讓系統時間和bios時間同步,用hwclock命令就行了命令列裡打 hwclock systohc或者這個命令的簡寫hwclock w就可以讓b...