2009-02-17 39 views
8

Tôi đã đọc chương 7 trong 'Trình điều khiển thiết bị Linux' (which can be found here) mà thời gian có thể được đo bằng 'jiffies'. Vấn đề với biến jiffies cổ phiếu là nó kết thúc tốt đẹp xung quanh khá thường xuyên (đặc biệt là nếu bạn có CONFIG_HZ của bạn đặt là 1000).Giờ hiện hành trong hạt nhân Linux 2.6

Trong mô-đun hạt nhân, tôi đang lưu giá trị jiffies được đặt thành một thời gian trong tương lai và so sánh giá trị này sau đó với giá trị 'jiffies' hiện tại. Tôi đã học được đã có những chức năng mà lấy bọc 32bit nháy mắt xem xét như vậy để so sánh hai giá trị Tôi đang sử dụng này:

if (time_after(jiffies, some_future_jiffies_value)) 
{ 
    // we've already passed the saved value 
} 

Ở đây có câu hỏi của tôi: Vì vậy, bây giờ tôi muốn thiết lập 'some_future_jiffies_value' thành "now + 10ms". Điều này có thể dễ dàng thực hiện bằng cách thực hiện việc này:

some_future_jiffies_value = jiffies + msecs_to_jiffies(10); 

Điều này có đúng không? Điều gì sẽ xảy ra nếu các jiffies hiện tại gần MAX_JIFFY_OFFSET và giá trị kết quả của msecs_to_jiffies (10) đặt some_future_jiffies_value quá khứ bù đắp đó? Liệu nó quấn quanh tự động hay tôi nên thêm một số mã để kiểm tra này? Có chức năng nào giúp tôi tránh phải đối phó với điều này không?

Cập nhật:

Để tránh nội dung với wraparound Tôi đã viết lại vòng lặp giấc ngủ của tôi:

// Sleep for the appropriate time 
    while (time_after(some_future_jiffies_value, jiffies)) 
    { 
     set_current_state(TASK_INTERRUPTIBLE); 
     schedule_timeout(1); 
    } 

Tôi giả định này là hơn đúng xách tay?

Cập nhật 2:

Thank you very much 'ctuffli' đã dành thời gian để trở về với câu hỏi này và cung cấp một số thông tin phản hồi về ý kiến ​​của tôi là tốt. Trình điều khiển hạt nhân của tôi hiện đang hoạt động tốt và nó kém hơn rất nhiều so với tình huống trước khi bạn cung cấp cho tôi tất cả các mẹo này. Cảm ơn!

+0

Một ý nghĩ khác: sẽ sử dụng get \ _jiffies \ _64() cứu tôi khỏi phải nghĩ đến việc bao bọc và chỉ để tôi làm toán đơn giản? – Benjamin

Trả lời

6

Những gì bạn đang thực hiện ở đây là về cơ bản msleep_interruptible() (linux/kernel/timer.c)

/** 
* msleep_interruptible - sleep waiting for signals 
* @msecs: Time in milliseconds to sleep for 
*/ 
unsigned long msleep_interruptible(unsigned int msecs) 

Chức năng này có ưu điểm là các đặc điểm kỹ thuật là bằng mili giây và ẩn các chi tiết của jiffies gói trong nội bộ. Hãy chắc chắn kiểm tra các giá trị trả về khi cuộc gọi này trả về số lượng các jiffies còn lại. Zero có nghĩa là cuộc gọi đã ngủ số mili giây được chỉ định trong khi giá trị khác 0 cho biết cuộc gọi đã bị gián đoạn nhiều cảnh báo sớm này.

Đối với bao bì, hãy xem phần 6.2.1.2 để biết mô tả về các gói và gói. Ngoài ra, điều này post cố gắng mô tả gói trong tóm tắt.

+0

Nếu tôi nhìn vào nguồn cho msleep_interruptible nó trông khá giống với thực tế! Tôi vẫn sẽ phải xem xét giá trị trả về từ hàm đó nếu tôi hiểu chính xác vì giấc ngủ gián đoạn có thể trở lại sớm hơn dự kiến ​​đúng không? – Benjamin

+0

Về việc đặt thời gian chờ quá MAX_JIFFY_OFFSET, bạn có biết liệu điều này có ổn không? Tôi thấy nó xảy ra rất nhiều trong các nguồn hạt nhân nhưng đây là một điều lý thuyết hơn tôi đã tự hỏi về. Cảm ơn bạn đã dành thời gian trả lời cho đến nay! :) – Benjamin

Các vấn đề liên quan