Câu chuyện từ khóa Volatile

Về từ khóa volatile thì có rất nhiều bài giải thích rồi, ví dụ như đây, đây đây nữa, tôi không muốn nhai đi nhai lại nhiều nữa.

Tuy nhiên vấn đề các tác giả đề cập đến thường là việc giá trị “biến thay đổi bất thường”, tôi không hiểu ý bất thường ở đây cụ thể là gì, bất thường đối với ai, nhưng có vẻ như là bất thường theo nghĩa trình biên dịch đọc code.
Để chắc bắp, nên tham khảo chính xác đặc tả C (or C++) xem nó nói gì, nhưng sờ vào đặc tả mới thấy nó không dễ đọc như tôi vẫn tưởng 😦

An object that has volatile-qualified type may be modified in ways unknown to the implementation or have other unknown side effects. Therefore any expression referring to such an object shall be evaluated strictly according to the rules of the abstract machine, as described in 5.1.2.3.

Có thời gian nữa thì chắc nên nghiền ngẫm thêm chút vì thuật ngữ nghe là lạ, nhưng có thể tạm hiểu là từ khóa volatile để chỉ ra rằng biến đó có thể được thay đổi theo cách không rõ, không nhận biết được (mk, tiếng việt mình ngu quá, dài dòng vậy chứ có khi dùng từ “bất thường” là hợp lý nhất), cho nên việc tham chiếu biến đó phải tuyệt đối tuân thử đúng qui tắc máy :-o. Kết hợp thêm các ví dụ tham khảo thì tôi đang tạm hiểu ý là những chỗ đã liên quan đến từ khoá volatile thì phải tuyệt đối làm theo đúng từng mệnh lệnh mà mã nguồn đã được viết ra.
Dùng Google tìm kiếm thì có thể tóm tắt vài tình huống dưới, mà biến bị thay đổi một cách bất thường đối với trình biên dịch, làm cho nó không nhận thức được việc thay đổi đó.
– Trong chương trình có xử lý ngắt, vì xử lý ngắt tạo tình huống đặc biệt.
– Xử lý song song đa luồng, các luồng có sử dụng biến chung.
– Vùng nhớ sử dụng cho IO map.
Chính vì trình biên dịch không có khả năng (?) nhận thức, nhận biết được toàn bộ những thay đổi liên quan đến biến có mang từ khoá volatile, do đó nó phải tuân thủ từng dòng code chứ không được suy đoán, mà mục đích thường là để tối ưu khi biên dịch mã nguồn.
Tôi thì vẫn nghĩ chỉ có trường hợp 3 do trình biên dịch không thể đủ thông tin nên mới có thể làm sai khi tiến hành tối ưu code, chứ trường hợp interrupt hay xử lý đa luồng, thì rõ ràng mọi thứ trình biên dịch đều có thể nhận thức được, tôi không cho rằng cái đó là biến được thay đổi một cách bất thường. Tuy nhiên vì chưa có hiểu biết gì về cách tối ưu của trình biên dịch nên tôi cũng chỉ đưa ra nhận định chủ quan.

Sau khi đọc bài viết chỗ này, tôi đã thử 1 sampe code để test với gcc 6.3.0, dùng signal interrupt từ bàn phím, nhưng tối ưu hóa đủ mọi option vẫn không bị lỗi. Sau khi được tác giả gợi ý dùng fake interrupt bằng timer thì lại đúng là bị lỗi nếu không dùng volatile thật.
Dù sao chăng nữa thì tôi vẫn giữ quan điểm volatile chỉ cần trường hợp map IO do tác động thực sự từ yếu tố bên ngoài mà trình biên dịch có mắt cũng chả thấy được, à hoặc có thể một trường hợp là cố tình dump code theo ý người viết, mà thường thấy là tạo delay  cái này thường thấy khi lập trình cho vi điều khiển, do thư viện không hỗ trợ hàm delay, điều này cũng làm cho trình biên dịch phán đoán là đoán mã đó thừa và thực hiện tối ưu, do nó không hiểu “ngu ý” của người viết. Còn lại với những trường hợp mà bản thân trình biên dịch có đầy đủ thông tin nhưng vẫn biên dịch lỗi nếu không có volatile thì tôi nghĩ có khi phải xem xét lại bản thân trình biên dịch.

Tóm lại từ khóa volatile dùng để nói cho trình biên dịch đấy là vùng cấm, code thế nào thì hãy làm đúng như thế, mày mới chỉ biết 1 chứ chưa biết 2, phần mày đang biên dịch chỉ là 1 phần nhỏ trong hệ thống lớn, nên đừng có khôn lỏi vào chỗ đó, đừng dựa vào nhận định chủ quan mà tiến hành thay đổi code để thực hiện tối ưu.

Câu chuyện đến đây có lẽ là xong rồi, tuy nhiên có lẽ  ta dễ thấy có gì đó hơi không tự nhiên lắm, do nó chỉ bị lỗi khi yêu cầu trình biên dịch thực hiện tối ưu, vậy nếu trình biên dịch “ngây thơ” bảo gì làm nấy thì có lẽ là ta chẳng cần từ khóa volatile làm gì. Mà về tính năng tối ưu trong trình biên dịch thì tôi nghĩ nó chỉ phát triển sau này. Lúc xây dựng C không rõ trình biên dịch mà cụ Dennis Ritchie dùng có những tính năng gì (tôi không rõ ông làm thế nào để xây dựng ra C nên chỉ phán đoán thôi, nhưng dù sao chắc cũng phải vừa xây dựng đặc tả thì cũng phải song song xây dựng 1 trình biên dịch để kiểm thử).
Kiểm ra lại đặc cả ngôn ngữ C phiên bản đầu tiên thì chưa có thật, nó chỉ được thêm vào từ phiên bản số 2. Từ đó liệu ta có thể phán đoán là trong quá trình phát triển tính năng tối ưu code của trình biên dịch, nó lại yêu cầu ngược lại đặc tả phải thêm từ khóa volatile?

Như vậy “điều lệ” ban ra đã rõ ràng, tuy nhiên “chi bộ” Kernel Linux lại không tuân thủ, à cũng nói thêm là “chi bộ” này được “đồng chí” Tovard Linux thành lập từ 1990 (chú ý là “đồng chí” Ngô Thời Nhiệm không nằm trong chi bộ này). “chi bộ” này đã ra 1 “thông tư” nói không với volatile cơ bản có 2 điểm.
1. Trong mọi trường hợp trong kernel linux đều không thấy cần volatile.
2. Nếu cần thì đấy là BUG.
“Thông tư” đã viết rất rõ ràng nên ai muốn biết mời tham khảo. Tìm hiểu thêm về “chi bộ” này ta còn bắt gặp nhiều điểm bất thường khác nữa, phải chăng chính điều đó tạo nên đặc trưng cho Kernel Linux.

Tham khảo
http://publications.gbdirect.co.uk/c_book/chapter8/const_and_volatile.html
http://publications.gbdirect.co.uk/c_book/

Biên dịch Linux OS từ mã nguồn

Bắt đầu đi làm vào giữa 2009, tôi bắt đầu được tiếp xúc với Linux, nhưng trải qua gần 9 năm từ đó đến nay, hiểu biết về Linux rất ổn định như tham nhũng, không có gì thay đổi. Lý do thứ nhất là vì các dự án làm với Linux chỉ là sử dụng môi trường Linux để phát triển, nên cơ bản chỉ biết cái Makefile là xong, chẳng lúc nào cần mó tay một cách chỉnh chu thấu đáo vào các thứ như device driver, hay memory management …, để biết cái gì đủ hay ho mà kể chuyện. Thật ra là có một chút nhưng không ăn thua, mấy thứ cơ bản như system call, char driver, block driver … thì nó phổ cập cmnr, với lại khoảng cách giữa biết tên và biết để kể chuyện được nó cũng quá xa. Lý do thứ 2 là lười & nhác tìm hiểu.

Đang ôn tập lại chút kiến thức để chuẩn bị do dự án làm driver trên Linux, thì bắt gặp trang dưới (ko hiểu sao giờ mới biết, chắc lại do nhác & lười).
http://linuxfromscratch.org/lfs

Trước giờ hay có sở thích, là thử distribution (Linux OS) của Linux, hết Ubuntu đến Backtrack, với mục đích rất đáng sợ là để học sâu thêm về Linux nhưng cài xong  chiêm ngưỡng cái desktop xong  rồi thì sau đó là chỉ để duyệt web ~.~

Việc hay thử Linux OS, nó cũng bắt nguồn từ hồi mới ra trường, được bố mẹ bán hết lúa gạo lợn gà cho mua con hp pavilion, không nhớ chính xác tên nhưng giá là 12 hay 17 chai gì đấy. Đen đủi thế nào lúc ra lúc bắt đầu đi làm 1 năm thì bị trộm nó thó mất, lương thấp ăn chưa đủ nói gì đến mua lại máy. May thay ông anh trong dự án có con T40 thinkpad hỏng main đang đắp chiếu, bảo cầm về sửa mà dùng. Sau thay main cũ hết 1 triệu, cài luôn ubuntu, có hơi rùa bò tí những nó vẫn dùng để kết nối tốt với internet. Vì rùa bò nên nghĩ ra việc dùng các bản Linux OS cho máy cấu hình thấp, nhưng rồi cũng thấy chẳng ăn thua lắm nên mới sinh ra trò thử cài Ubuntu xong gỡ hết gói màu mè về giao diện ra thì tốc độ có thấy cải thiện kha khá. Từ đó có thêm trò ngược đời là cài xong Linux OS thì gỡ bớt gói không cần thiết ra, đôi khi không biết nên gỡ quá tay làm nó chẳng start up luôn được cả giao diện =]]. Dùng được hơn 1 năm thì T40 cũng đi vì cái màn hình hỏng.

Đến 2011, đi công tác ở Nhật, nhịn ăn nên cũng mua được con CF-W5MW8AJR Panasonic đồ cũ cùi bắp, mua xong cài luôn Ubuntu đè lên con Win Vista bản quyền luôn.
Riêng con này từ lúc mua ngoài làm mất thứ vớ vẩn thì cũng kiếm đc chút từ việc
data hiding, do muốn mua con len Nikon 50mm f/1.8G, nhưng lương chỉ đủ nuôi con nên đành kiếm tí việc đánh thêm, đỡ phạm đến phần tiền mua sữa cho con 😦

Nói dài dòng, nhưng tóm lại giờ có con CF5 cùi bắp, tính  cho mấy thằng em ở quê, nhưng chắc là nó không thèm lấy, mà công nhận đồ của Panasonic rất chất, nhẹ, pin trâu vẫn duy trì hơn tầm 1.5h, phím bấm cực đã không bị rung, ai dùng dòng Let’s Note của Panasonic rồi thì biết, chỉ có điều giá trên trời. Như  đề cập ở trên, tự dưng biết 1 dự án rất có tâm, hướng dẫn biên dịch hẳn Linux OS từ source code (có khi google đủ các kiểu + bỏ thời gian ra chắc cũng tự build được), tóm lại từ Linux kernel, đến các gói mã nguồn GNU & non-GNU …

Dù là việc biên dịch chỉ là việc chân tay, nhưng trải nghiệm 1 lần biên dịch ra OS từ mã nguồn nó cũng hay hay, dù sao cũng tạo hứng thú vượt qua lười & nhác để có thể bắt đầu tìm hiểu thêm chút về Linux. Thêm vào đó hi vọng do tự điều chỉnh được các gói cần thiết nên sẽ có được con OS nhỏ gọn để chạy với cái đồ cùi bắp như CF-W5MW8AJR.

Có 1 điểm chú ý khi bắt đầu biên dịch là nên chuẩn bị 1 con USB stick hoặc CD live có thể chạy live Linux OS nào đó (ex: ubuntu), để phòng trường hợp lỗi khi chia ổ cứng này nọ thì còn có cách mà xử lý.
Về phần dữ liệu quan trọng trong máy thì theo tôi không cần phải backup, vì nếu bị lỗi thì có cơ hội học cách cứu dữ liệu, nếu cứu không được thì coi như cái giá phải trả để nhớ bài học hơn =]].