January 30, 2006

Secret Maryo Chronicles : Mario 遊戲的新實做


[Secret Maryo Chronicles] 的前身是 "Super Mario Clone",顧名思義,就是經典遊戲 Mario Brother 的重新實做版本,因為有商標侵權的議題,於是改名,是個以 GPL 授權發行的遊戲,完成度很高。

我很久沒有打電動,之所以會找到這個遊戲,只是因為昨天看 HBO 的電影《逃往美國》,發現劇中男主角很像 Mario Brother (真是可愛的喜劇阿),讓我突然手癢。從 Wikipedia 找到相當詳細的介紹:[Mario]

雖然有很多遊戲的實做,不過記得以前讀過 Shawn Hargreaves 的文章 [Playing the Open Source Game],所以就在 Freshmeat 找了一下。Debian 有收錄 [SuperTux],可是我不喜歡,Mario 換成企鵝,這還像話嗎?所以後來就用 [Secret Maryo Chronicles (SMC)] 了。

SMC 最新的版本是 0.97,但是 source tarball 裡面有些 bug,並且打包方式也不太正確,我修了一部分並重新打包,可 [下載修正過的 SMC 0.97],執行畫面如下: (click to enlarge)

感謝 Secret Maryo Chronicles 團隊的付出!
由 jserv 發表於 12:33 PM | 迴響 (0)

Redefining The CEO

Ragnarok Studio 針對 BusinessWeek 的 slideshow [Redefining The CEO] 做了精彩的介紹與眉批,可參考 [Redefine CEO]。開場人物就是以被認為最有影響力 CEO 之一的 Steve Jobs:

由 jserv 發表於 02:29 AM | 迴響 (0)

January 29, 2006

真空管專利長長99


這個標題下得真奇怪,就跟我在 Google 找多媒體的資料,竟然找到 [真空管 (Vacuum tube)] 一樣。真空管分成二極管 (Diode) 與三極管 (Triode),分別如下面兩張圖:
Diode:

Triode:

Jack Ganssle 的文章 [Ninety-nine years ago] 提到,在 99 年前的一月,Lee De Forest 以真空管獲得美國專利 #841,387,Jack Ganssle 這麼描述真空管的重要性:
    The tube could arguably be the most important invention in the history of electronics, for it introduced for the first time the concept of an active element. Tubes could amplify, rectify, and work as logic components. Though transistors eventually supplanted these devices for most applications, there's really nothing that a transistor can do that a tube can't.

    Before tubes there were no consumer electronic products. No cell phones, stereos, or even monos; wax cylinders and (to a lesser extent in the early years) disks transmitted music via a needle coupled directly to a loudspeaker-like horn. This technology was entirely mechanical and was devoid of a single wire.
真空管算是開創消費性電子的濫觴,所以我在 Google 找多媒體出現真空管,不算是意外了,事實上,真空管的精神長存,且讓其「長長99」吧 (「長長」是指真空管的長度與影響力,99 是說專利的歷史)。
由 jserv 發表於 11:32 PM | 迴響 (0)

ToyWM : 體驗 ICCCM 與 EWMH 規格的練習

或許已經有些朋友知道,我最近在寫個小型的 Window Manager,為什麼要再寫一個呢?新書《揭開 X Window System 神秘面紗》將會用一定的篇幅介紹 ICCCM 與 EWMH,而我覺得,沒有創作過 Window Manager、沒有在開發的過程中遇到挫折,進而改進之,就不算理解這些 spec (同樣的,書中探討 X Input Method 的部份,也會實做一個 XIM server from scratch,老實說,書什麼時候會寫完,我根本不知道 *笑*)。是此,ToyWM 就誕生了,運作畫面如下圖:

重點會落在 Window Management,探討 Substructure Redirection (如 Xlib 的 XLowerWindow() / XMoveResizeWindow() / XMoveWindow() / XRaiseWindow() / XResizeWindow() 等 API)、Reparenting,以及重點 Window Manager Hints。並且會從 winman 的分析與修改作出發,探討 ToyWM 建構的過程,希望近期內可以完成。
由 jserv 發表於 10:04 PM | 迴響 (1)

農曆新年

剛剛警衛跟我打招呼的時候,我才赫然發現今天是中國農曆正月。不太喜歡生活的環境擺月曆,所以對時間一直沒感覺,[ccal] 這隻程式可以印列農曆 (GPL 授權),執行畫面如下:

其實打 "ccal -u" 就可以輸出 UTF-8,我自作聰明罷了。ccal 的功能很多,也支援 EPS、PDF,以及 JPEG 的輸出,今年的月曆:(click to enlarge)

由 jserv 發表於 07:45 PM | 迴響 (0)

Visual BASIC 9.x 與 duck typing

Visual BASIC 與 Delphi 是少數我在 Win32 喜歡的開發環境,小時候曾經用這兩套開發過中型的 GIS (地理資訊系統),不過主要的程式碼還是用 Delphi 寫的,VB 充其量是拿來拉 UI 與作簡單的測試工具,那樣的記憶一直停留在腦海 (從上個世紀到本世紀),直到閱讀這篇由一位 MVP 撰寫的 blog [VB的日益動態化],徹底改變我對 Visual BASIC 的看法。

VB 9 引入 Dynamic Interface 與 Dynamic Identifiers 的概念,這部份的介紹可參考 MSDN [Overview of Visual Basic 9.0] 中 [Dynamic Interfaces (or Strong "Duck Typing")] 與 [Dynamic Identifiers] 兩個子項目。當然,這些技術都不算新了,早在 Smalltalk 的時代,就有完整的實做,那為何 Dynamic interface 又稱為 Strong "Duck Typing" 呢?首先來看 Wikipedia 對於 [Duck Typing] 的解釋:
    In computer science, duck typing is a term for the dynamic type system typical of some programming languages, such as with Smalltalk, where the variable value itself determines what it can do. It also implies that as long as an object implements a certain interface, it is interchangeable with any other object that implements the same interface, no matter whether the two have a related inheritance hierarchy.

    The name combines two metaphors, both to make a serious point, and to make a joke. Initially used in the context of dynamic typing by Dave Thomas in the Ruby community, its premise is that if it walks like a duck, and talks like a duck, then it might as well be a duck. One can also say that the language ducks the issue of typing.
電腦科學就是這麼有趣,總是用些生動的比喻來描述這些概念。Ruby community 的 Dave Thomas 將動態語言中,物件特徵的描述用以下的話語作比喻:
    if it walks like a duck, and talks like a duck, then it might as well be a duck.
這裡的 it 當然是表示 object,如果走起路來像鴨子,叫起來也像是鴨子,那麼一定是隻鴨子,saucer 的 blog [VB的日益動態化] 舉了很好的例子,這裡就不贅述了。而 Dave Thomas 的比喻,讓我不直覺想起 Edgar Allan Poe 在《創作哲學》的詩句:
    照在牠身上的燈光把牠的陰影投射在地板;
    而我的靈魂,會從那團在地板上漂浮的陰暗
    被擢升嗎 -- 永不復返!
這是對烏鴉的象徵,不過拿來作 duck - Object 的描述,似乎也是不錯的輔助資訊。物件導向總有高度的抽象意味,true polymorphism 的實踐,萬物 (object) 在可見度褪化為虛幻的陰影,一旦具體的形貌被抹除,Object 得以自由的變化,詩人的靈魂與鴨子的生命,在某種觀點來說,是一致的,卻又在不同軀殼有了獨特的行為...
由 jserv 發表於 05:34 PM | 迴響 (0)

通訊地址

之前在 [演講:Linux 國際化與區域化發展] 與 [演講:綜觀 X Window System 新發展 (台中場次)] 曾俏皮的說過:
    如果您願意贊助本人作些 open source 的開發或研究,不見得要用金錢資助,也可以在過年過節寄賀卡,這樣我就會很開心,有動力繼續做下去...
大致意思是這樣,而我也忘記到底是哪一場演講中說的,沒想到昨天竟然收到一封 email,除了跟我拜年外,還跟我要通訊地址,想要寄賀卡給我 *大驚*

聽起來很新鮮呢,畢竟我已經很少收到賀卡了,這裡就公佈小弟的通訊地址:
    台北市114,內湖區瑞光路500號八樓
收件人是「黃敬群」。總之,感謝各位的鼓勵與支持,新年快樂!
由 jserv 發表於 04:29 PM | 迴響 (0)

探索 Linux Memory Model (下)

延續 [探索 Linux Memory Model (上)],翻譯 IBM 軟體工程師 Vikram Shukla 的文章 [Explore the Linux memory model]。

Paging model in general
如前面所提,paging unit 轉換 linear addresses 為 physical address,一組 linear address 聚集為 page,linear addresses 本質上是連續的,paging unit 對映這些連續的記憶體為對應真實記憶體位址,稱為 page frames。注意,paging unit 讓 RAM 切割為固定大小的 page frame 成為可見的。[譯注:我們也得以邏輯上存取到實體的 RAM]

因為如此,paging 有以下優點:
  • 一個 page 所規範的存取權限,將可安全的限制一段位於 page 中 linear address 的使用
  • page 的長度等於 page frame 的長度
用以對應這些 page 到 page frame 的資料結構,稱為 page table,儲存於主記憶體中,並會在 paging unit 使用前,由 kernel 妥善初始化,下圖表示 page 到 page frame 的比對與對映關係:


注意 Page1 的 address 與 Page Frame1 的對應 address 相符。

在 Linux 中,paging unit 的使用不僅是 segmentation unit,就如我們之前在 Linux 與 segmentation 所見,每個 segment descriptor 使用相同的 linear addressing 集合、讓 segmentation unit 轉換到 logical address 的轉換使用量降到最少。透過這種對 paging unit 的使用方式,Linux 大幅降低跨越多種不同硬體平台的 memory management 與 portability 困難度。


paging 中所需的資訊
這裡描述了在 x86 架構中 paging 所需的資訊,這對於 Linux 實現 paging 很重要。paging unit 作為 segmentation unit 輸出中取得 linear address,稍後則表示為以下項目:
  • Directory 是以 10 MSBs (Most Significant Bit 是二進位表示法中,最高的 bit,有時也指最左的 bit) 表示
  • Table 是以中間 10 bits 表示
  • Offset 是以 12 LSBs (Least Significant Bit 是二進位表示法中,最低的 bit,有時也指最右的 bit) 表示
轉換 linear address 為其對應的實體 addressing 是個兩階段的程序。第一步使用稱為 Page Directory 的轉換表格 (從 Page Directory 到 Page Table),而接下來使用 Page Table 的表格進行轉換 (Page Table 外加所欲的 page frame 的 Offset),示意如下圖:

Page Directory 的 physical address 載入於 cr3 register,linear address 的 directory 欄位決定指向正確 Page Table 的 entry,而 The address in table field determines the entry in the Page Table that contains the physical address of the page frame containing the page. The offset field determines relative position within the page frame. [譯注:保留原文,這個形容詞子句實在太難翻譯了] 既然 offset 量為 12 bits,每個 page 包含了 4 kb 的資料量。

簡述實體記憶體位址的計算方式:
  • cr3 + Page Directory (10 MSBs) = 指向 table_base
  • table_base + Page Table (10 個中間的 bits) = points to page_base
  • page_base + Offset = physical address (取得 page frame)
既然 Page Directory 與 Page Table 長度都是 10 bits,可定址的範圍就是 1024 * 1024 kb,並且 Offset 可以定址到 2^12 (4096 bytes),因此,全部由 Page Directory 規範的可定址範圍就是 1024 * 1024 * 4096 (等於 2^32 = 4 GB)。所以,在 x86 硬體架構來說,可定址的上限就是 4 GB。


Extended paging
Extended paging 是由移除 Page Table 轉換表並且 linear address 的劃分是由 Page Directory (10 MSB) 與 Offset (22 LSB) 的改變而來的。22 LSBs 對 page frame 產生 4 Mb 的上限值 (2^22),extended paging 與正常的 paging 是共存的,並且可對應到更大的連續 linear address。作業系統透過設定 PSE (page size extension) flag,移除 Page Table,因而提供 extended paging

36-bit PSE 擴充了 36-bit 實體記憶體定址支援到 4 Mb pages,而 maintaining a 4- byte page-directory entry thereby providing a simple mechanism to address physical memory above 4 GB without requiring major design changes to operating systems. [譯注:這裡是精髓] 因此,這個途徑對於要求 paging 有了實際的限制。


Linux 的 paging model
Linux 的 paging 機制很接近上述的一般性 paging,不過 x86 架構引入了 three-level page table 機制,包含以下項目:
  • Page Global Directory (pgd) - 多層次 page table 之上的抽象層面,每個 page table 的 level 處理不同大小的記憶體,global directory 也可能會處理 4 Mb 大小的區域。每個 entry 會是指向較小 directory 的較低層面的 table,所以 pgd 是 page table 的 directory。當程式碼存取這個結構 (某些 driver 會有此動作),就稱為 "walk" 了 page table。
  • Page Middle Directory (pmd) - page table 的中間層面。在 x86 架構中,pmd 並非存在於硬體,但包含在 kernel code 的 pgd 實做中。
  • Page Table Entry (pte) - 直接與 page 處理的底層,對照到 PAGE_SIZE 這個數值定義,包含 page 和對應 bit 的實體記憶體 address。例如,當 entry 是有效的,表示相對的 page 存在於真實記憶體中

為了支援 large memory area,three-level paging 模式也與 Linux kernel 協同運作。當沒有要求 large-memory-area support [譯注:Kernel configuration 選項] 時,會回到 two-level paging,並且 defining the pmd as "1." [譯注:這部份不太懂,還待釐清]。這些 level 在編譯時期就最佳化處理過,enabling both the second and third levels (using the same set of code) by just enabling or disabling the middle directory. The 32-bit processor uses pmd paging and 64-bit processors use pgd paging. [譯注:這部份不太懂,還待釐清]

就如你所知,在 64-bit 處理器中:
  • 21 MSBs 並未使用
  • 13 LSBs 以 page offset 表示
  • 剩餘的 30 bits 切割為:
    • 10 bits 給 Page Table
    • 10 bits 給 Page Global Directory
    • 10 bits 給 Page Middle Directory
從這個架構可見,真正用以定址的,只有 43 bits,所以在 64-bit 處理器上,可用的 virtual memory 量就是 2 的 43 次方。

每個 process 有其獨立的 page directory 與 page table,而為了去參考包含真正使用者資料的 page frame,在 x86 架構,作業系統開始載入 pgd 到 cr3 register 中。Linux 將 cr3 register 存入 TSS segment 的內容中,並在一個新 process 開始在 CPU 執行時,將另一個 TSS segment 的值載入 cr3 register 中。這導致 paging unit 參照目前 page table。

Each entry into the pgd table points to a page frame containing an array of pmd entries which in turns points to a page frame containing pte which finally points to a page frame containing the user data. [譯注:又是複雜的形容詞子句,還是建議直接去翻《Understanding the Linux Kernel, Third Edition]》第二章的圖表] 如果嘗試找尋的 page 已被 swap out,一個 swap entry 會儲存於使用中的 pte table (當有 page fault 被觸發時),找尋記憶體中待 reload 的 page frame。

下圖顯示我們正在每個對應到 page frame entry 的 pae table level 新增 offset,我們透過打破 segmentation unit 的輸出 linear address,獲得 offset。而為了打破對應到每個 page table 的 linear address,需要在 kernel 中使用多個 macro,不過這裡不會探討這些 macro 的細節,而是看看 linear address 的切割。



保留的 page frame
Linux 保留少數 page frame 給 kernel code 與資料結構使用,這些 page 永遠不會被 swap 到磁碟中。從 0x0 到 0xc0000000 (PAGE_OFFSET) 之間的 linear address 為 user code 與 kernel code 所參照,而 PAGE_OFFSET 到 0xffffffff 的部份,則由 kernel code 所定址。這意味著,即便硬體定址的範圍達 4GB,但只有 3 GB 是給使用者應用程式的定址。


paging 是如何運作的?
在 Linux process 所採用的 paging 機制可分為兩個階段:
  • 開機階段,系統準備 page table 給 8 Mb 的實體記憶體所用
  • 之後,完成實體記憶體的 reset 對應動作
在開機階段,startup_32() call 負責初始化 paging,實做程式碼位於 arch/i386/kernel/head.S 檔案中,上述的 8 Mb 對應發生於 PAGE_OFFSET 位址之上。初始程序起始於編譯時期靜態定義的 swapper_pg_dir 陣列,在編譯時期置放於 0x00101000 特定的位址中。

此舉建立給兩個靜態定義的 page -- pg0 與 pg1 的 page table entry,這些 page frame 的大小預設為 4 kb,除非 page size extension bit 被設定 (請參考前面 Extended paging 的部份,以得知 PSE 的資訊)。指向 global array 的 data address 儲存於 cr3 register 中,作者認為是前述第一階段為 Linux process 設定 paging unit 時。其餘 page entry 是在第二階段所設定的,第二階段是由 paging_init() 呼叫所開始的。

RAM 的對應是在 PAGE_OFFSET 與 x86 32-bit 架構的 4 Gb 上限 (0xFFFFFFFF) 之間位址完成的,這表示約莫 1 GB 的 RAM 可在 Linux 起始時作對映動作。然而,如果設定 HIGHMEM_CONFIG,超過 1 GB 的真實記憶體也會對映到 kernel - 請記住,這是暫時的記憶體配置安排,這些是由 kmap() 呼叫所完成。[譯注:這部份的「魔法」還有許多變化空間,KernelTrap.org 的文章 [Linux: Using 1GB of RAM Without HighMem] 可以看到最近的一些突破,由 Jens Axboe 起草,並且獲得 Linus Torvalds 與 Ingo Molnar 的 feedback,整個討論 thread 都很值得參考]


Physical memory zone
前面作者已經提過在 IA32 架構下,Linux kernel 以 3:1 的比例切割 virtual memory,也就是 3 GB virtual memory 給 user space,而 1 GB 是 kernel space 所用,而 kernel code 與其資料結構必須常駐 [譯注:「常駐」似乎是 DOS 時代 TSR 常見的術語,不過因為這部份不會被 swap out,所以譯者認為這樣的翻譯很適當] 於定址空間上層的 1 GB 中。不過,定址空間更大的使用者是 physical memory 的 virtual mapping。

這個 mapping 的存在是因為如果記憶體驅動沒有 map 到 kernel 定址空間,kernel 無法管理該記憶體區段,也因此,the maximum amount of physical memory that could be handled by the kernel was the amount that could be mapped into kernel's virtual address space minus the space needed to map the kernel code itself. [譯注:又是複雜的形容詞子句] 在 x86 運作的 Linux 可以在真實記憶體 1 GB 以下運作。[譯注:在 LKML 中,Linus Torvalds 提出以下的看法:
    since PAE depends on the 3G/1G split (we could make it work for a pure 2G/2G split, but that's a separate issue, and then we'd need to change the CONFIG_PAGE_OFFSET defaults to be something like
      default 0x80000000 if VMSPLIT_2G && X86_PAE
    (but that's definitely not appropriate for now - that's a separate issue, after somebody has verified that PAE and 2G:2G works)
J.A. Magallon 補充道:
    Basically the option boils down to how much virtual address space you want to assign to the kernel and user space. The kernel can always access all of memory, but in some cases part of that memory will be available as high memory that needs to be mapped in first (see references to kmap() and kmap_atomic() in the kernel). So whether changing the mapping or using highmem is the best option for you, depends entirely on what you run on that machine. If you require a huge user address space, then you don't want to change away from the 3/1 user/kernel default setting. However, if you don't need the full 3G of adress space to user apps, then you are better off increasing the kernel address space range to get rid of the high memory mapping.

    For the "typical" case of 1GB machine, using the _OPT setting to just move the offset slightly is a really good choice as it only removes a little bit of the user address range.
不過譯者認為作者只是一般性的描述,畢竟這議題實在是相當複雜,就不拘泥字句了。]

為了服務更多使用者、支援更大的記憶體、改善系統效能,並且建立與硬體架構無關的記憶體描述方式,Linux memory model 必須作充分的修改。為了達成以上目標,新的模式將記憶體劃分為給每個 CPU 的 bank,而每個 bank 就稱為一個 node,每個 node 切割為若干個 zone。Zone 作為記憶體的範圍表示,有以下分類:
  • ZONE_DMA (0-16 MB) - 包含設定 ISA/PCI 裝置所需的較低實體記憶體區域的範圍
  • ZONE_NORMAL (16-896 MB) - 直接由 kernel 對映上層實體記憶體區域的範圍,所有的 kernel 操作只能在該 memory zone 中發生,也因此,這是對系統效能有最大衝擊的區域
  • ZONE_HIGHMEM (896 MB 或更高) - 並未被 kernel 所對映的剩餘有效記憶體區域
node 使用的概念在 kernel 中是透過 struct pglist_data 所實做的,zone 則是由 struct zone_struct 所表示,實體的 page frame 則是由 struct Page 表示。並且,這些資料結構會保存於 global structure array struct mem_map,而這又儲存於 NORMAL_ZONE 的開端。下圖顯示 node、zone,以及 page frame 之間的關聯:

high memory zone 的出現於 kernel memory management,開始於 Pentium II 的 virtual memory extension 被實做 (以透過 PAE 存取到 64 GB 的記憶體,PAE 是 Physical Address Extension,存在於最近的 IA32 架構),並且支援 4 GB 實體記憶體。這個概念被應用於 x86 與 SPARC 平台上,一般來說,4 GB 記憶體是透過 kmap() 呼叫,對映 ZONE_HIGHMEM 到 ZONE_NORMAL 之上作為存取。請注意,在 32-bit 硬體架構安置超過 16 GB 的 RAM 並不是明智的舉動,即便 PAE 是有效的。
    (PAE is an Intel-provided memory address extension that enables processors to expand the number of bits that can be used to address physical memory from 32 bits to 36 bits through support in the host operating system for applications using the Address Windowing Extensions API.)
physical memory zone 的配置是由 zone allocator 所完成,這個 zone allocator 負責分割記憶體為若干 zone,視每個 zone 為 unit for allocation purposes。Any particular allocation request utilizes a list of zones from which the allocation may be attempted, in a most-preferred-to-least-preferred order.[譯注:譯者還沒理解這部份的實做,不翻譯]

舉例來說:
  • A request for a user page should be filled first from the "normal" zone (ZONE_NORMAL)
  • if that fails, from ZONE_HIGHMEM
  • and if that fails, from ZONE_DMA
The zone list for such allocations consists of the ZONE_NORMAL, ZONE_HIGHMEM, and ZONE_DMA zones, in that order. On the other hand, a request for a DMA page may only be fulfilled from the DMA zone, so the zone list for such requests contains only the DMA zone.


結論
Memory management 是個複雜又令人費解的巨大工程,像是 scheduling、paging,以及 multiple-process 之間的交互運作,是相當大的挑戰,作者希望本文可協助讀者建立基本的知識,以理解 Linux memory management 設計與實做的議題,作為一個出發點。


參考資料
[譯注:終於翻譯完了,也多了許多 hacking tasks]
由 jserv 發表於 03:57 PM | 迴響 (0)

M$ Inside 的 ATM 提款機

記得兩年前,曾差點接下某個 Kiosk 的案子 ,當時為了那個案子,還特別流連在捷運站導覽系統與 ATM 提款機前面,觀察其原理,雖然那不過是 Computer Science 基本的 Finite State Machine 罷了,但是面對這種案子,還是必須謹慎才是,否則...

我們看看負面的效果,請參考 cookys 的 blog [ATM 提款機 crash],M$ Inside 加上沒有妥善的測試 (意外?),引用 cookys 的眉批:
    重開機完仍然有一分鐘左右的時間沒有鎖定螢幕,仍然能夠取得滑鼠的控制權,這實在令人很無言….然後再跑了兩三分鐘,就跑成:「暫停使用」了。有趣的是,當中有某人進來存錢大概被嚇到了,搞不清楚這幾個人是在做什麼,那時很想告訴他「諾,這就是我們校外 OS 實習啊 XD」

帥阿!老皮。
由 jserv 發表於 01:19 PM | 迴響 (2)

January 28, 2006

探索 Linux Memory Model (上)

以下翻譯 IBM 軟體工程師 Vikram Shukla 的文章 [Explore the Linux memory model],重要的技術術語我保留不翻譯,行文也稍調整,翻譯也主要是閱讀時的筆記,或許不甚流暢。

標題: 探索 Linux Memory Model
原作: Vikram Shukla (vikshukl@in.ibm.com), Software Engineer, IBM
繁體中文翻譯: 黃敬群 (Jim Huang / jserv)
最後更新日期: 24 Jan 2006

理解 Linux Kernel 中的 memory model 是揭開 Linux 複雜設計與實做層層布幕的第一步,本文將給予關於 Linux memory model 的入門等級介紹。

Linux 採用 monolithic 途徑以規範基本操作,或用以實做作業系統服務的系統呼叫的集合,這些包含了執行於 supervisor 模式中若干模組的 process management、cocurrency,以及 memory management。[譯注:相對於 Linux kernel 的 monolithic 途徑,就是 1990 年代相當熱門的 microkernel 設計,以第二代 microkenel 設計的代表 L4 來說,in-kernel 的系統呼叫不過 12 個 (傳統的 kernel 則有兩百以上之譜),上述的模組則獨立存在,以 Fast IPC 作溝通] 並且。雖然 Linux 基於硬體相容性考量,維護了 segment control unit model [譯注:這是 Intel 80386 保護模式的術語,文後的參考書籍《Understanding the Linux Kernel, Third Edition]》在這個主題有相當清楚的闡述],不過在最小層次來說,仍採用這個模式。與 memory management 相關的主要議題有:
  • VMM (Virtual Memory Management) - 對應用程式記憶體需求與實體記憶體的邏輯上分層機制
  • Physical memory management
  • Kernel virtual memory management / kernel memory allocator - 用以提供記憶體需求與配置的元件,這些需求可能是來自 kernel 或從 user 端。
  • Virtual address space management
  • Swapping 與 caching
本文將協助讀者從 memory management 的角度,來理解 Linux kernel 內部的以下行為:
  • segment control unit model - 通論以及 Linux 的行為
  • paging model - 通論以及 Linux 的行為
  • memory zone 的實際細節
本文無法詳細探討 Linux kernel 管理記憶體的細節,但文後關於 memory model 與其定址處理的概念將對理解細節有很大的助益,並且儘管本文著重於 x86 硬體架構,不過同樣的概念可以推廣到其他硬體架構。[譯注:IBM developerWorks 其他文章有探討 Linux 在 PowerPC 硬體架構的議題,很值得參考]

x86 記憶體架構
x86 分成以下三種記憶體定址方式:
  • logical address - 顧名思義,這段 adress 與實體記憶體是邏輯上的關聯 (直接或間接),通常用在一個 controller [譯注:包含 Linux Device Driver] 要求資訊時
  • linear address (或 flat address space [譯注:在 Intel Developer Manual 中後者較常見]) - 以 0 作起點的記憶體區段,後繼的 byte 計數則遞增,如 0, 1, 2, 3, ... 等,直到記憶體區段的終點,這是絕多數非 x86 架構的硬體採用的設計 [譯注:特別是 ARM 與 MIPS 這類的 RISC]。Intel 採用的配置方式則迥異於前,透過 64 kb 長度的 segment 切割記憶體, 伴隨 segment register 指向特定 segment base address,用以表示目前使用中的 segment。在 Intel 32 位元的硬體架構 [譯注:也就是 IA32],可視為 flat address space,但使用了 segment
  • physical address - 實體記憶體 bus 所表示的記憶體範圍 [譯注:特別是在硬體 Block diagram 可見區域],與前述的 logical address 相較,physical address 的差異在於 memory management unit,該單元是轉換 logical address 到 physical address
x86 CPU 使用兩個單元來作 logical address 到 physical address 的轉換,分別是 segmented unit 與 paging unit,示意圖如下:

接下來,將探討 segment control unit model。

Segment control unit model 通論
segmentation model 背後的基本想法是以一組 segment 來作記憶體管理,每個 segment 都有專屬的 address space。每個 segment 由以下兩個部份組成:
  • base address - 內含特定實體記憶體位址的 address
  • length value - 指定該 segment 的長度

以 segment 劃分的 address 也包含兩個部份: segment selector 與 offset into segment。前者描述了欲使用的 segment,而欲使用的 segment 也內含 base address 與 length value,而後者針對真實的記憶體存取,指定了自 base address 的 offset (偏移量)。對映到實體記憶體,真實的記憶體就是 offset 與 base address 值的和 (sum),倘若 offset 值超過了 segment 的長度,系統會產生 protection violation。以扼要的文字描述:
    Segmented Unit 表示為 -> Segment: Offset model 也可以表示為 -> Segment Identifier: Offset
每個 segment 是個 16-bit 的欄位,稱為 segment identifier 或 segment selector,x86 硬體有一些可程式化的 register,稱為 segment register,可保存這些 segment seletor。這些 register 是: cs (code segment)、ds (data segment),以及 ss (stack segment)。每個 segment identifier 識別以 64-bit (8 bytes) segment descriptor 表示的 segment,這些 segment descriptor 儲存於一個 GDT (Global Descriptor Table),也可能儲存於 LDT (Local Descriptor Table) 中,示意圖如下:


每次 segment seletor 載入到 segment register 時,對應的 segment descriptor 會自記憶體載入到非可程式化的 CPU register。每個 segment descriptor 是 8-bytes 的長度,並在記憶體中以單一 segment 表示,儲存於 LDT 或 GDT 中。The segment descriptor entry contains both a pointer to the first byte in the associated segment represented by the Base field and a 20-bit value (the Limit field) which represents the size of the segment in memory. [譯注:抓不到感覺,保留原文,直接參考下面的圖可以協助理解]

其他欄位包含了特殊的屬性,像是 privilege level 與 segment type (cs 或 ds),segment type 是以 4-bit 表示的 Type 欄位。

因為我們使用非可程式化的 register,當 logical address 到 linear address 轉換進行時,GDT 或 LDT 不會受到影響,這可加速記憶體轉換的速度。

segment selector 包含以下項目:
  • 13-bit index - 識別在 GDT 或 LDT 中對應的 segment descriptor entry
  • TI (Table Indicator) flag - 如果 TI flag = 0 表示 segment descriptor 在 GDT,而若是 1,表示 segment descriptor 在 LDT 中
  • RPL (request privilege level) - 定義當對應 segment selector 載入於 segment register 時,目前 CPU 的 privilege level
既然 segment descriptor 的長度是 8 bytes,其在 GDT 或 LDT 的相對 address 可由 segment selector 最前面 13 bits 與 8 的乘積獲得。比方說,如果 GDT 儲存於 address 0x0002000,且 segment selector 的 Index 值為 2,那麼,對應的 segment descriptor 為 (2*8) + 0x0002000 。可儲存於 GDT 的 segment descriptor 的總和為 (2^13 - 1),也就是 8191 。下圖表示了從 logical address 取得 linear address 的過程:

以上就是 Segment control unit model 的一般性介紹 [譯注:看到這裡,想必一定開始頭暈了,建議閱讀《Understanding the Linux Kernel, Third Edition]》前三章,書中有更詳盡的圖表與描述],那 Linux 有什麼特別之處呢?

Segment control unit in Linux
在 Linux 中,前述的模式有了小量的修改。作者已經注意到 Linux 以較為侷限的方式,使用 segmentation model:在 Linux 中,所有 segment register 指向相同範圍的 segment address,換言之,每個 segment register 使用同一組的 linear address,這讓 Linux 得以使用有限數量的 segment descriptor,因此,所有 descriptor 可保持於 GDT。這個模式的優點有兩項:
  • 在所有 process 使用相同的 segment register 值 (當分享相同組的 linear address),Memory management 可更簡單
  • 達到多數硬體架構可支援的可攜性,有些 RISC 處理器也支援這種侷限的 segmentation [譯注:像是 Sun Sparc]
下圖展示 Linux 的修改模式,由此可見 segment register 指向一組相同的 address:


Segment descriptors
Linux 使用以下 segment descriptor:
  • kernel code segment
  • kernel data segment
  • user code segment
  • user data segment
  • TSS segment
  • 預設 LDT segment
讓我們進一步探討。

在 GDT 中的 kernel code segment descriptor 有以下數值:
  • Base = 0x00000000
  • Limit = 0xffffffff (2^32 -1) = 4GB
  • G (granularity flag) = 1 表示 pages 中的 segment size
  • S = 1 表示正常的 code / data segment
  • Type = 0xa 表示可被讀取與執行的 code segment
  • DPL value = 0 表示 kernel mode
與此 segment 相關的 linear address 為 4 GB,S = 1 與 type = 0xa 參考該 code segment,seletor 位於 cs register 中。在 Linux kernel 中,可透過 _KERNEL_CS macro 來存取對應的 segment selector。

對 kernel code segment 來說,kernel data segment descriptor 有相似的數值,除了 file Type 被設定為 2,這表示了該 segment 為 data segment,並且 selector 儲存 ds register。在 Linux kernel 中,可透過 _KERNEL_DS macro 來存取對應的 segment selector。

user code segment 為所有的執行於 user mode 的 process 所分享,在 GDT 中對應的 segment descriptor 有以下的數值:
  • Base = 0x00000000
  • Limit = 0xffffffff
  • G = 1
  • S = 1
  • Type = 0xa 表示可被讀取與執行的 code segment
  • DPL = 3 表示 user mode
在 Linux kernel 中,可透過 _USER_CS macro 以存取該 segment selector。在 user data segment descriptor 中,唯一有更動的欄位是 Type,更動為 2,表示為可被讀取與寫入的 data segment,在 Linux kernel 中,可透過 _USER_DS macro 以存取該 segment selector。

除了上述的 segment descriptors,GDT 對於每個建立的 process 還有兩個 segment descriptors: TSS 與 LDT segments。

每個 TSS segment descriptor 指向不同的 process,TSS 保留每個 CPU 硬體的 context information [譯注:最少包含 register 與狀態值],以便於 context switch 的過程中使用。舉例來說,從 User mode 切換到 Kernel mode 時,x86 CPU 會從 TSS 取得 kernel mode stack 的 address。

每個 process 有其獨立的、對應該 process (decriptor),並且儲存於 GDT 中的 TSS descriptor,該 descriptor 有以下數值:
  • Base = &tss (對應 process descriptor 的 TSS field 的 address,例如 &tss_struct) - 定義於 Linux kernel 的 schedule.h 檔案中
  • Limit = 0xeb (TSS segment 長度為 236 bytes)
  • Type = 9 或 11
  • DPL = 0. user mode 不會存取 TSS,所以 G flag 是清除的
所有的 process 分享預設的 LDT segment,一般情況下,LDT segment 包含了空的 segment descriptor。預設的 LDT segment descriptor 儲存於 GDT 中,Linux 所產生的 LDT 有 24 bytes,預設情況下,以下三個 entries 總是有效的 (present):
    LDT[0] = null
    LDT[1] = user code segment
    LDT[2] = user data/stack segment descriptor

Calculating TASKS
為了要計算 GDT 中最大的 permission entries,知悉 NR_TASKS (用以決定 Linux 對於同時執行的 process 數量,在 kernel source 中預設為 512,允許最多 256 對單一 instance 的連線數量) 是必要的。允許在 GDT 中的 entries 總和可用以下計算式決定:
    GDT 的 entries 數量 = 12 + 2 * NR_TASKS
    在文章前面已經提過,x86 硬體中,GDT 可有的 entries 數量 = 2^13 -1 = 8192
[譯注: NR_TASKS 這個 macro definition 首次出現於 Linux 的「參考對象」Minix 中,在 Linux kernel 改版時,曾經從 sched.h 移到 tasks.h]
8192 segment descriptor 之外,Linux 使用六個 segment descriptors, 另外四個用以 APM 功能 (advanced power management features),還有四個在 GDT 中的保留未使用,因此,在 GDT 中可能的數量為8192 - 14 = 8180 。

在任何時間,在 GDT 中不可能有超過 8180 個 entries,因此:
    2 * NR_TASKS = 8180
    NR_TASKS = 8180/2 = 4090
為什麼要 2 * NR_TASKS 呢?因為對每個建立的 process 來說,不只有 TSS descriptor (用以維護 context-switch 的 context) 會被載入,而且 LDT descriptor 也會被載入。

在 x86 的數量限制過去在 2.2 kernel 是個議題,不過自從 2.4 kernel 開始,這個問題消除了,部份是因為 context switching (這讓使用 TSS 成為必然) 與硬體關聯的抽離,並且引入 process switching 所致。

接下來,我們來探討 paging model。
(待續...)
由 jserv 發表於 08:30 PM | 迴響 (1)

January 27, 2006

快快樂樂用 mimeTeX

用了一個晚上在演繹經典的火柴棒問題,還推導了一些數學式,試著記錄下來,原本用 pdfLaTeX 打,不過發現如果要放到 blog 上,還是要剪貼,不直覺,剛剛想起有 [mimeTeX] 可用,感謝 chihchun 協助設定,我已經在 people.debian.org.tw 裝好了。使用方式很簡單,如果要插入 LaTeX,就這麼寫: (為了排版需要,做了額外的分行)
    <img src="http://people.debian.org.tw/~jserv/cgi-bin/mimetex.cgi?
    \Large\hspace{5}\unitlength{1}
    \picture(175,100)
      {~(50,50){\circle(100)}(1,50)
      {\overbrace{\line(46)}^{4$\;\;a}}(52,50)
      {\line(125)}~(50,52;115;2){\mid}~(52,55)
      {\longleftar[60]}(130,56){\longrightar[35]}
      ~(116,58){r}~(c85,50;80;2){\bullet}
      (c85,36){3$-q}~(c165,36){3$q}
      (42,29){\underbrace{\line(32)}_{1$a^2/r\;\;\;}}~}"
    alt="Demo \picture" border=0 align=middle>
    
顯示的效果如下:
Demo \picture

希望春節期間,能繼續多唸點書,思考這類經典的問題,並作點整理。
由 jserv 發表於 11:50 PM | 迴響 (2)

Orz 之「考前總整理」

好不容易,我的感冒併發症終於在掙扎 2.5 週後痊癒,不過體力還沒恢復到可以 [醉 coding] 的程度,只好每天唸點書、看看 datasheet,以及算些數學。年節時分,就來點輕鬆的,以下從我的 RSS 訂閱中,搜尋出跟 "Orz" 有關的 entries,就當成下次「考前總整理」的參考資料吧。
以下為隨機順序: 剛剛改了 [Debian 蝸牛 (Debian snail) 和 ubuntu 花 (Ubuntu flower)],弄個 Orz Flower:

用 GIMP 繪製時,腦海浮現 Gabriel Garcia Marquez 的經典著作《百年孤寂》,第七章寫道:
    ... 木匠給死者量棺材尺寸時,看見窗外下起了細微的黃花雨。整整一夜, 黃色的花朵像無聲的暴雨,在市鎮上空紛紛飄落,鋪滿了所有的房頂,堵塞 了房門,遮沒了睡在戶外的牲畜。天上落下了那麼多的黃色花朵,翌日早晨 ,整個馬路彷彿多鋪了一層密實的地毯,所以不得不用鏟子和耙子為送葬隊 伍清除道路。
而我,則是目睹滿滿的 Orz 花朵,在目光可及處飄曳...
由 jserv 發表於 08:59 PM | 迴響 (0)

新春愉快恭禧發財的 TeX 範本

新年快樂!

剛剛在 moto.dot 瞥見李果正前輩的 post [Re: 恭祝新年快樂],他用 TeX 製作了以下動畫圖檔:

原始 TeX 可 [在此下載]。
由 jserv 發表於 08:01 PM | 迴響 (0)

Hyper Liu : Web-based 蝦米

[Hyper Liu] 是 Luke Chang 的作品,提供 web-based 蝦米測試練習環境,非常棒!

由 jserv 發表於 06:09 PM | 迴響 (0)

GuarantorTo_be_Killed Toolkit

"GuarantorTo_be_Killed Toolkit" 聽起來頗奇怪,到底是什麼呢?解釋前,先來看看今天早上跟 PCMan 聊天的內容 (in #dot IRC channel):
    07:53:19 pcman : gtk+ tree model 有非常嚴重的 bug
    07:53:31 pcman : 我被迫停止開發了 T_T
    07:53:42 pcman : GtkTreeModelSort 整個根本是壞的
    07:54:07 pcman : 去看 source code 才發現裡面的註解:連開發者自己都不確定那個會不會動
    07:54:29 pcman : 文件裡面竟然沒有警告..... 我在大量使用後發現一堆解決不掉的問題,最後一點辦法都沒有了......
    07:55:15 pcman : 連用奇怪的 workaround 都沒辦法處理....
    07:55:43 pcman : 是可以用 GtkListStore 本身的 GtkTreeSortable interface
    07:55:54 pcman : 只是這樣又不能共用 model
    07:55:54 jserv-- : 真麻煩 XD
    07:56:01 pcman : 每種 sort 要自己一份
    07:56:12 pcman : memory 使用量大增
    07:56:34 * jserv-- 還是用 mc
    07:56:38 pcman : 然後剛剛發現... XFCE Thunar 採用的方案是...自己寫 custom model.... 他根本就不用 gtk+ 的
    07:56:51 pcman : 怒........@_@ 努力了這麼久到剛剛有種上當的感覺
    07:57:16 pcman : 去看 bug report 發現沒人提到,感覺這根本是個大家沒在用的東西
    07:57:50 pcman : 我上次已經偷了 ExoIconView, patch 一下可以用
    07:58:08 pcman : 但這次這個.... 如果用他的我得整個重寫,而且那個沒法共用 child model
    07:58:34 pcman : 那我還不如改用 GtkTreeSortable 然後各 tree view 各 copy 一份 model
    07:58:44 pcman : 這樣應該不會壞
    07:58:51 pcman : 只是很可惜的吃 RAM
    07:59:25 pcman : 但看來是目前唯一可以動的方法.... 沒辦法了,很大一部分得重寫
    07:59:34 jserv-- : !! 07:59:45 pcman : 下次不要用 gtk+ 了
    08:00:23 pcman : 生氣了生氣了.... 被文件耍了半天,debug 好幾天受不了 hack 進去才發現 那根本是爛的 @@
    08:00:46 pcman : 不確定能不能用的東西竟然放在正式版本 release 出來,文件上也沒有警告 = =
    08:01:19 pcman : 這還是 2.8... 一般人使用最多的 2.6 還不知道藏著什麼鬼 bug... 越想越恐怖
    08:01:50 * pcman 開始覺得去 TnLug 講完 gtk+ 簡介後,應該要呼籲大家不要使用.......
    08:02:25 jserv-- : [Orz] pcman 寫 code 被 Gtk+ 耍,難道... GuarantorTo_be_Killed Toolkit ?
    08:03:25 pcman : 這回是真的怒了..... /* WARNING: this code is dangerous, can cause sleepless nights, can cause your dog to die among other bad things. we warned you and we're not liable for any head injuries.
    08:03:52 pcman : 文件上應該把這段寫進去.... 竟然藏在 source code 裡面,害我用得很高興
    08:04:47 jserv-- : 寫 browser 最忌諱這種 unknown behavior :(
    08:05:17 pcman : 最慘的是寫到最後階段,一直有解決不掉的 bug,才發現問題根本來自底層 toolkit......
    08:05:33 pcman : 差一點就寫完了,然後被迫放棄重來 = =
    08:05:59 jserv-- 果然 Gtk+ = GuarantorTo_be_Killed Toolkit
    08:06:30 jserv-- : 找不到擔保人,Nobody cares
    08:06:31 jserv-- : Orz
PCMan 最近的大作是 [PCMan File Manager],而他詬病的部份就是 Gtk+ 的 GtkTreeModelSort,其 source code 可參考 [gtk+/gtk/gtktreemodelsort.c],在一開頭就這麼寫到:
    /* WARNING: this code is dangerous, can cause sleepless nights,
     * can cause your dog to die among other bad things
     *
     * we warned you and we're not liable for any head injuries.
     */
    
這個 "GuarantorTo_be_Killed Toolkit" 真是複雜到不行 :(
由 jserv 發表於 03:24 PM | 迴響 (2)

January 25, 2006

下一代的 SCIM 設計

蘇哲在 SCIM mailing-list 張貼了下一代的 SCIM (version 2.0) 的架構設計,可參考 [Some thought of the future of scim.],韓國開發者 krisna 在他的 blog [SCIM 2.0 design] 將 mailing-list 的 dia 轉換成圖檔: (click to enlarge)

在新的設計中,Message BUS 是相當重要的元件,摘錄蘇哲文字的重點:
  • Message BUS will be a separated process acting as a central message transfer hub. It'll be a socket server, lisening on a local unix socket.
  • IMEngine Provider is a special client of Message BUS, which loads all IMEngine modules and real Config module, and exports the services to Message BUS through socket.
  • Helper Module are also clients of Message BUS, which can communicate with applications and IMEngines through Message BUS.
  • All applications are also clients of Message BUS, which get input method services from Message BUS by a small wrapper (similar to Socket IMEngine).
  • All clients of Message BUS are reloadable, for example, IMEngine Provider can be reloaded without breaking any applications.
  • Message BUS is a process which has no binary dependency to any other modules or libraries, except c, c++ and scim core library. And it has very small footprint, so that it can be very stable.
  • All GUI components are independent Helper modules which run in separated processes. So that they are all reloadable and replaceable.
  • GUI Setup module will also be Helper modules, so that they can be implemented with any widget libraries.
乍看之下,有些 IIIMF 中 IIIM Protocol Resource/Transaction management 的意味,不過應該更為輕量級,或許,直接支援 D-Bus 來作為 message bus 也是個途徑?不過,我好像有點安於現狀,無暇去關心 IM Framework,現在我的問題都來自酷音輸入法本身 :(
由 jserv 發表於 10:04 PM | 迴響 (1)

January 24, 2006

Device Driver 開發者的告白

呂不韋懸賞改《呂氏春秋》一字千金的故事,在白話文通行的現代,已經難以復見,不過對於 Device Driver 的開發者來說,每個 magic number、每個 shift,甚至是微小的 timing 變化,都是影響 Device 是否能驅動的關鍵,為此往往需要透過大量的測試與 test cases 來驗證,比照其薪資待遇,「一字千金」早已無法形容,隨著專案的複雜度變化,「萬金」或「千萬金」都有可能。[Trimo's Note] 分享了其 Device Driver 開發的經驗 [ Bit-bashers],用很淺顯有趣的文字,帶過這開發過程,值得一看。

話說回來,最近也在搞 low-level programming,有個硬體我已經弄了一個月,還是沒進展,真糟糕 :(
由 jserv 發表於 10:54 AM | 迴響 (4)

January 23, 2006

KDE4 的發展方向

LinuxDevCenter.com 刊載了一篇 Aaron J. Seigo 的專訪 [Previewing KDE 4],Aaron J. Seigo 是全職的 KDE Developer,而他負責許多下一代 KDE 的核心技術,像是 [Plasma]。KDE4 不只是建構於更強大的 Qt4,而且隨著硬體與 Free/Open source software 的蓬勃發展,許多過去「只聞樓梯響」的概念,也有機會實現了,令人高度期待的 KDE4 :-)

由 jserv 發表於 08:09 PM | 迴響 (0)

Web 2.0 展示

還沒有時間涉獵 Web 2.0,[Netvibes界面UI分析] 後,提到 [Netvibes] 是 blog 作者認為目前做得最好的 Web 2.0 網站。[Netvibes] 使用 client-side Javascript / CSS 搭配 server-side HTTPRequest,應該就是所謂的 Ajax 技術,的確做得非常棒,剛剛還玩了好一段時間,我想,如果能整合 JSR168 (Portlet),或許更有威力。

不過,server-side 距離我好遠,現在頂多作些 Realtime system designs 會接觸 server,其他都在 handheld devices 了。我看到這個網站時,第一個反應竟然是檢查 W3C HTML Validation,以及研讀其 page source。

由 jserv 發表於 07:47 PM | 迴響 (0)

BSD 冷光面板

Edwardc 長輩繼 BSD iCash 之後又一力作 -- [LumiBSD],LumiBSD 冷光面板的照片如下:

發光 !
cool !
由 jserv 發表於 06:10 AM | 迴響 (0)

Nagle's algorithm 與 PCManX

Cisco 的文件 [Managing System Performance] 這麼提到:
    Limit TCP Transactions

    When using a standard TCP implementation to send keystrokes between machines, TCP tends to send one packet for each keystroke typed, which can use up bandwidth and contribute to congestion on larger networks.

    John Nagle's algorithm (RFC 896) helps alleviate the small-packet problem in TCP. The first character typed after connection establishment is sent in a single packet, but TCP holds any additional characters typed until the receiver acknowledges the previous packet. Then the second, larger packet is sent, and additional typed characters are saved until the acknowledgment comes back. The effect is to accumulate characters into larger chunks, and pace them out to the network at a rate matching the round-trip time of the given connection. This method is usually good for all TCP-based traffic. However, do not enable the Nagle slow packet avoidance algorithm if you have XRemote users on X Window sessions.
不過以前讀的時候沒有很仔細思考,剛剛閱讀 [Boost socket performance on Linux] 時,才想到 [PCManX] 的確有改進空間,於是著手修改,ChangeLog 如下:
    * src/view/telnetcon.cpp (CTelnetCon::ConnectAsync): Disable the Nagle (TCP No Delay) algorithm. Nagle algorithm works well to minimize small packets by concatenating them into larger ones. However, for telnet application, the experience would be less than desirable if the user were required to fill a segment with typed characters before the packet was sent.
[Nagle's algorithm] 也就是 [RFC896],是 John Nagle 提出用以縮減網路傳輸過程中的封包數量,這一過程稱為 nagling,對於 traffic control 有顯著效益,不過對於 telnet 這類小封包資料傳遞的應用程式來說,如果 disable Nagle algorithm,可提昇反應速度,在 socket programming 中,這個 flag 通常是 TCP_NODELAY 。

除了 [PCManX],在 X Window System 的實做中,也需要 disable Nagle algorithm。在 Ubuntu Dapper 安裝 xtrans-dev (X transport library) 後,會有以下檔案: (按:為什麼 -dev 的套件中,會有 source code?)
    jserv@venux:~$ dpkg -L xtrans-dev
    /usr/include/X11/Xtrans/transport.c
    /usr/include/X11/Xtrans/Xtrans.c
    /usr/include/X11/Xtrans/Xtrans.h
    /usr/include/X11/Xtrans/Xtransdnet.c
    /usr/include/X11/Xtrans/Xtransint.h
    /usr/include/X11/Xtrans/Xtranslcl.c
    /usr/include/X11/Xtrans/Xtransos2.c
    /usr/include/X11/Xtrans/Xtranssock.c
    /usr/include/X11/Xtrans/Xtranstli.c
    /usr/include/X11/Xtrans/Xtransutil.c
    
與平台相關的部份是 Xtranssock.c ,其內部實做如下:
    static XtransConnInfo
    TRANS(SocketINETAccept) (XtransConnInfo ciptr, int *status)
    {
      ...
        XtransConnInfo      newciptr;
        struct sockaddr_in  sockname;
        int                 namelen = sizeof(sockname);
        if ((newciptr = (XtransConnInfo) xcalloc (
            1, sizeof(struct _XtransConnInfo))) == NULL)
        {
            *status = TRANS_ACCEPT_BAD_MALLOC;
            return NULL;
        }
    
        if ((newciptr->fd = accept (
            ciptr->fd,
            (struct sockaddr *) &sockname, 
            (void *)&namelen)) < 0)
        {
            xfree (newciptr);
            *status = TRANS_ACCEPT_FAILED;
            return NULL;
        }
    
    #ifdef TCP_NODELAY
        {
            /*
             * turn off TCP coalescence for INET sockets
             */
    
            int tmp = 1;
            setsockopt (newciptr->fd, 
                IPPROTO_TCP, TCP_NODELAY,
                (char *) &tmp, sizeof (int));
        }
    #endif
    
[[200 OK]: A Port80 Software Blog] 有篇 [TCP_NODELAY: To Nagle or Not To Nagle?] 可作為參考。
由 jserv 發表於 04:38 AM | 迴響 (1)

鑽孔機的科學原理 : Reuleaux triangle

在台北內湖工作的我,時常可見捷運工程趕工的情況,許多以前沒見過的機械,也紛紛現身。鑽孔機的變化,是讓我比較有興趣的,普通的鑽孔機可鑽出圓孔,像是下圖:
但是基於捷運線路銜接的需要,有許多正四邊形的鑽孔,並且在刀刃的設計,也有其特別處,如圖:

可對應到鑽孔機運作,我們可以發現刀刃切割 (移動) 的範圍,就是所期待正四邊形的形狀,將旋轉的過程分解,可得到下圖:

用餐的時候回憶起高中曾研習過相似的議題,剛剛醒來才找到資料,這鑽孔設計的科學原理就是 Reuleaux triangle。在探討 Reuleaux triangle 前,需要參考 [Curve of constant width],也就是由等寬弧線構成的幾何,Reuleaux triangle 是其中的特例。先建構正三角形,邊長為 r,以各頂點為圓心作圓:

如此可得覆蓋正三角形區域的範圍:

十九世紀的德國工程師 Franz Reuleaux 廣泛的應用這個幾何原理,作機械應用,並也以 Reuleaux 命名。考慮以下機械設計:

Reuleaux 在這個矩形範圍內旋轉,也可以發現,事實上移動的範圍是圓邊的矩形,該圓邊又是橢圓軌跡的一部分:

給定外圍矩形的頂點座標是 (+/- 1, +/- 1),可得橢圓方程式:
    x = 1 - cos(Beta) - sqrt(3) * sin(Beta)
    y = 1 - sin(Beta) - sqrt(3) * cos(Beta)
Beta 的範圍落於 PI/6 與 PI/3 之間:

又由笛卡爾方程式,得知 Reuleaux triangle 涵蓋面積為 2 * sqrt(3) + PI/6 - 3,計算值為 0.9877003907
中心的移動軌跡不見得是圓形,如果改以橢圓軌跡,可得到更大的涵蓋:

Paul Kunkel 提供了 Java applet 作為模擬,可參考 [Reuleaux Triangle],而他也探討一系列變形的 Reuleaux triangle 可能性。

除了機械應用,真實環境下,英鎊的硬幣就是 [Curve of constant width] 有趣的例子:


推廣到五邊 (Twenty Pence) 與七邊 (Fifty Pence) 的 Reuleaux polygon (2n + 1)。

參考資料:
由 jserv 發表於 02:10 AM | 迴響 (5)

January 22, 2006

那個大霧的時代 : 成大共產黨案

生活在安定繁榮的台灣,擁有一份足以溫飽的工作,行有餘力則作文或 hacking 自娛,這是平凡者如我,最確切的寫照,而我也安於現況。然而,成長的歷程中,累積的疑惑始終盤據腦海深處,特別是學生時代發生的巨變:六四天安門事件、台獨運動、解嚴、鄭南榕自焚、政治犯陸續出獄、蘇俄垮台、柏林圍牆倒塌、... 等等。我當時不過是國小的學童,但我很慶幸親眼目睹時代的更迭,原本只愛好邏輯推理的我,一時之間,茫然了,學校老師與報紙媒體給我的「解釋」實在相當不合邏輯,於是只得在苗栗鄉下,從很侷限的藏書找尋這一切的關聯性...

考取台中一中,到了繁華的大都市唸書,除了視野的開闊外,就是對中國近代史,以及這塊我立足的寶島所發生的事件,有了新的體悟,與其說對歷史產生興趣,毋寧說這是一種權責,我有知的權利,更有釐清真相的責任。2003 年,李敖出版了《紅色11》,以劇本形式影射牢獄中的所見所聞,生動的揭露台灣白色恐怖時代的歷史,引述 [博客來書籍館] 的介紹:
    「紅色」即是指共產黨,「11」則是牢房號碼,在這間牢房裡,除了有「共匪」外,還關了叛亂犯、小偷、流氓、老師。藉由這些角色,李敖寫出了各類人遭遇打擊下的心態轉變,有人更憤世嫉俗,有人皈依信教,有人仍舊渾渾噩噩。全書一片陽剛之氣,毫無半點柔情,但男人間的真情流露,絕對令人動容。
書中的歷史事件就是成大共產黨案,發生在我出生前十年,雖然在成大就讀時,耳聞大學教授提及,不過一直到今日才知悉整個事件。

《臺灣歷史辭典》對於「成大共產黨案」的描述如下:
    1971年11月成功大學學生蔡俊軍、吳榮元、鐘俊隆、吳俊宏、余光夏、沈寧怡等在校內圖書館閱讀《資本論》、《馬克思主義與唯物史觀》等社會主義書籍、信奉社會主義,草擬宣言,成立「成大共產黨」,由蔡俊軍任主席,吳榮元任副主席,鐘俊隆擔任書記。成員除成大學生外,另有淡江學生林擎天、林守一、張建章,輔大李國龍,文化學院李代雄,逢甲學院李慧宗、吳錦江,高雄商業學校黃文珍,空軍幼校林台雄、刁德善、張星戈、鄧伯宸,海軍官校余子超等學生。 1972年2月陸續被捕,以意圖顛覆政府著手實行罪名,3月移送警總軍法處。同年10月3日判決,蔡俊軍、吳榮元判處死刑;鐘俊隆、吳錦江、林守一、林擎天等4人無期徒刑;張建章、吳俊宏、沈寧怡、刁德善、張星戈、黃文珍等6人處15年徒刑;鄧伯宸等7人交付感化教育3年。由於此案被告均為19至24歲的大學生,引起立法委員質詢,何以在大學和軍校接受教育之後,思想轉變傾向共產黨。美國方面亦表示關切。1972年12月國防部發回軍法處更審。1973年 2月更審結果,死刑改判無期徒刑,無期徒刑改判15年,其餘維持原判。
自由時報副刊曾連載〈那個大霧的時代〉,由鄧伯宸口述、鄧湘庭紀錄整理, 原本一篇大一學生的口述歷史報告,不過口述歷史的主人翁正是「成大共產黨案」的涉案者之一,標題〈那個大霧的時代〉用以描述白色恐怖,再適切不過。走在冥霧氤氳的道路上,動員戡亂與種種不安的陰影,揮之不去,霧中疾行的陰影,在厭世的氣氛中淪喪飄泊的方向,迷惘著凝視迂迴的路,抑或失卻,抑或禁錮,然真相何在?全文可參考自由生活藝文網: 今日我可以輕鬆下筆,不必擔心明日會神秘失蹤,儘管內心還是沈重的,沒有這些前輩的奮鬥,不會有今日。不管是採用什麼途徑,但民主的花蕾還是綻放了,在美麗的台灣,謹此對以鮮血灌溉民主幼苗的前輩們致敬。
由 jserv 發表於 12:56 PM | 迴響 (6)

January 21, 2006

Thomas L. Friedman 的《世界是平的》

我很少讀當季暢銷書,並不是因為我只讀經史子集,而是我認為,當季暢銷書所要闡述的理念,很多時候會被滿滿的書評蓋過,多少會有些誤差,不過昨天去誠品書店看書,還是買了 Thomas L. Friedman 的暢銷書作《世界是平的》。賦閒在家,思考《世界是平的》所提到的巨變,那些已經發生的一切,以及我們未來在新的基準點,所面臨的共同挑戰與合作關係。


《世界是平的》簡介可以參考 [博客來書籍館],同時,作者 Thomas L. Friedman 在去年也應 MIT 的邀請進行了演講,相關的介紹與錄影,已經放到 [麻省理工學院開放式課程]。我在台大計中的伺服器做了一份 [錄影 mirror] (MPEG-4 格式,240x180),朱學恒先生翻譯了中文字幕,不過我發現 MPlayer 播放起來會有問題,所以做了 [中文字幕修正],播放方式如下:
    mplayer Friedman-MIT-2005-05-16.avi -sub Friedman-MIT-2005-05-16 -subcp cp950 -subfont-text-scale 5 -font /usr/share/fonts/truetype/arphic/ukai.ttf
除了中間關於 open source 的描述有點讓我不知所云外 (像是沒有微軟,還會造成 open source 運動質疑,以及如報紙記者看待 Firefox 集中於兩位年輕開發者一般,卻忽略真正的衝擊在於 Mozilla 計畫的意義等等,不過我想,大概是我的理解有問題),這的確是相當有啟發性的演說。

不過我比較有興趣的還是第11章:「對許多人來說,世界一點都不平」,這個議題在演說尾聲有 MIT 的學生問及,不過 Thomas L. Friedman 給的答覆讓我又陷入新的謎題:g11n 也就是 globalization,造成的衝突,以及引來更劇烈的「力量上的差異」(套用書中用詞),我們能預期的解決方式,看來還是跟保守的現況類似,為什麼要呢?(再度套用書中用詞)
由 jserv 發表於 02:32 PM | 迴響 (5)

哈希表

在解釋「哈希表」之前,先來說故事。

話說最近在 hack Linux kernel 時,遇到許多資料結構上的問題,我們相當清楚,kernel hacker 總是喜歡使用「手工最佳化」來幫不夠聰明的 C compilers 作它們該做的事情,那些技巧已經不能用 tricky 來形容,簡直就是巧奪天工阿,所以呢,研讀 kernel source 前,一定要先行研讀基本的分析。找到一篇對岸的文件,內文出現「哈希表」的字眼,我當時在想,這是什麼玩意?!難不成是... ?! 後來才發現的確是 "Hash table"。

好神奇的翻譯阿,這讓我聯想,"Null Cache" 豈不要翻譯成「吾爾開希」,這位大陸民運領袖的名字?
由 jserv 發表於 02:38 AM | 迴響 (8)

January 19, 2006

Pareto principle

Pareto principle 也就是我們常聽到的 "80/20 Rule",詳情可參閱 Wikipedia 的 [解釋],這裡整理相關的語錄:
(1)
    The Parento Rule
    "vital few and trivial many" ...that 20 percent of something is reponsible for 80 percent of the results
      Dr. J.M Juran
(2)
    It's a fact that applications spend 80 percent of their time executing 20 percent of their code. Some ven claim that the ratio is higher: 90-10
      www.devx.com
(3)
    DSP app? 80-20 rule still works
      EE Times

由 jserv 發表於 02:33 PM | 迴響 (0)

Crazy UI engine

Crazy UI engine 是我最近的新實驗,從 Xorz/Embedded 作出發,體驗進階繪圖技術在 Embedded System 的實現。我的參考平台是 Intel Xscale PXA27x,目前已經完成一部分的模擬與概念驗證:

上圖展示 Crazy UI engine 對於 gradient 的支援,並且整個 window management 也引入 Sports Model,換言之,圖中選單項目的切換,會伴隨 wobbly效果, 是個很有趣的實驗。至於 "gradient",引用 [About.com] 的解釋:
    Definition: A gradient, or graduated fill, is a color fill that gradually blends from one color to another. A gradient can contain more than two colors, all fading smoothly from one to another. Gradients are very useful for creating shading for three-dimensional and metallic effects. Most graphics software allows you to create a variety of gradient effects such as linear, radial, reflected, diamond, conical, and angle. Some software even offers gradient mesh effects, which allows you to create elaborate shading by plotting colors to each of the intersections of an imaginary mesh, so that the colors all blend together. In the example image you can see several types of gradients, including a 3D button created simply by using two opposing linear gradient fills.
未來,可能會參考 [Kernel Graphics Interface] 與 [FBUI] 對於 Kernel-mode graphics 的 full acceleration,不過 PXA 27x 在這點相當薄弱,所以可能只是列為遠程目標。
由 jserv 發表於 12:24 PM | 迴響 (1)

江城如畫裡 山晚望晴空

嘉卡爾曾說:「雖然我的羽翼被緊縛著,但我的心卻很自由;監獄的牆壁雖能阻止我逃逸,但不能束縛我靈魂的自由。」,身陷於這個「數位監獄」中,獨攬許多難以負荷的事務,部份是出自意願,其餘則是被迫,還得裝成一副欣然接受的樣貌。我已經很少涉足步行無法抵達的地區,某種程度來說,的確是無法脫逃環境的禁錮,但無論如何,靈魂仍是自由的。

如之前的 blog [美景不需遠求] 與 [內湖俯瞰] 所提及,不經意的捕捉俯拾即是的美景,不僅是份樂趣,更是讓自己停下來體驗落葉風飄、靜下來聆聽花開花謝,寧靜與自省思中,得以與大自然共鳴,體驗無止息的神秘力量。

上個月,一如往常騎著淑女車趕內湖科學園區工作,在瑞光路瞥見雨後天晴的虹彩: (click to enlarge)

這讓我想起兒時背誦李白的詩作《秋登宣城謝眺北樓》:
    江城如畫裡,山晚望晴空。
    兩水夾明鏡,雙橋落彩虹。
    人烟寒橘柚,秋色老梧桐。
    誰念北樓上,臨風懷謝公?
    
當然,圖片的意境遠不如李白所描述,不過得以於「數位監獄」欣賞這少見的美景,羽翼雖仍被緊縛,但「江城如畫裡,山晚望晴空」,觀彩虹與流雲共日,美麗的詩篇在藍天中畫下純真的標點,而我,持以赤子之心,何嘗不能自由的掙脫呢?

同時,也讓我想到尼采著名的詩集《Lieder des Prinzen Vogelfrei》,擅長運用德文隱晦複雜構字的尼采,在詩名給予我們頗多揣測的空間。Vogelfrei 是 Vogel 與 frei 組合而成,字面的意思是「如鳥一般自由」,而之前又冠上王子 (Prinzen) 的頭銜,那 Vogelfrei 看來又是人名,在詩作中的意境,又可以發現其實這一切是「王子」、「自由的」,以及「鳥」交互詮釋。此際,振翅高飛的我,離虹彩越來越近,心境的變化只能用尼采的詩作刻劃:
    喔!信天翁!
    我也從體內永恆地追求著高飛與昂揚,
    我眺望著你的方向,
    是的,我愛你
    而,淚水,已然決堤如洪
    
隨著鍊帶的牽引,最後抵達辦公室,在圖像一隅展開了工作的內容,執行「數位監獄」的勤務,望著晴空,這美景久久盤據於心...
由 jserv 發表於 01:32 AM | 迴響 (0)

January 18, 2006

新版本的 Qt/Embedded 將改名為 Qtopia Core

Trolltech 的 Qt/X11、Qt/Embedded,以及 Qtopia 在 open source community 與商業應用開創了雙贏的局面。如果有跟 Trolltech 有商業往來的開發者可以發現,去年購買 Qt/Embedded 與 Qtopia Commercial License 時,即區分了 "Core" license,以及上層 Qtopia stack 的部份,而 Qtopia.net 的新聞稿 [Trolltech Expands Qtopia Embedded Technology Products with Qtopia Core] 證實產品更名的訊息,基於 Qtopia 的成功,新版本的 Qt/Embedded 更名為 Qtopia Core,並且是以 Qt4 為基礎,許多重大的改進在稍早的 blog [Trolltech 終於釋出 Qt4] 提過,現在 software stack 如下圖:

並且 Qtopia 的 profiles 也更多元,允許 3-rd parties 開發加值產品。

至於 GPL 發行的 Qtopia Core,Trolltech 已經悄悄的放上 [qt snapshots] 上,我正在測試 qtopia-core-opensource-src-4.1.1-snapshot-20060117,近期希望能將 GNU Classpath 的 Qt4 AWT peer 與 kBrowser 移植到 Qtopia Core 並作驗證 (TODO)。
由 jserv 發表於 10:03 AM | 迴響 (0)

檢視 GPL 3.0 草案

Free Software Foundation 在美國時間 Jan 16, 2006 釋出第一份 [GNU GENERAL PUBLIC LICENSE Version 3 Discussion Draft],在我開始研讀 GPL 3.0 草案 (以下簡稱 GPLv3) 之前,先收集相關的評論與報導: 我試著歸納幾個分析 GPLv3 的重點:
  • 時空背景
      GPL v2 已經有 15 年的歷史,Richard Stallman 當初的 "copyleft" 概念訴諸於 GNU General Public License,雖然證實是可行且有法律性的參考,但問題是其中隱含對於軟體或是韌體方法的不明確,是需要釐清的,以 Java 的例子來說,Java 是動態語言,而一旦某個 package 被授以 GPL,其衍生著作的範疇是否涵蓋「執行時期的 linkage」呢?韌體 (firmware) 也是另一個灰色地帶,其軟體性的行為,以及 GPL 追溯的效力,需要透過更明確的規範。
  • 數位財產的保護法令
      DRM 是 "Digital Rights Management" 或 "Digital Restrictions Management" 的縮寫,是這個世紀相當重要的科技考量,在 GPLv3 對 DRM 有所著墨,這部份必須視國情與國際法規而定。
  • 軟體專利
      軟體專利是個相當複雜的議題,特別扯上 "copyleft" 時,以 Linux Kernel 來說,雖然很明確的規範以 GPL v2 發行,而且多數的開發者或廠商也依據 GPL v2 釋出其 Linux 的衍生物或創作內容,然而我們可以發現類似 RT-Linux 這類將特定軟體方法申請專利後,雖然 rtlinux patch (也就是 RTLinux Free edition) 符合 GPL v2 規範,不過衍生創作仍有侵犯專利的可能性,為此還需要簽署一份 Open Patent License,某種角度來說,已經與 "copyleft" 的四大自由有所出入。GPLv3 關於軟體專利的規範,可參考 Section 2 (Basic Permissions)、Section 6 (Non-Source Distribution),以及 Section 7 (License Compatibility),在前面提到 James McPherson 的 blog,究竟 Sun's Common Development and Distribution License (CDDL) 是否與 GPLv3 相容呢?在軟體專利反制條款有所出入,這點也可對照「排他」與「互惠條款」的部份。
  • 從 "distribution" 到 "propagation" 用詞的改變
      這讓我想到,以前 BSD 在柏克萊大學發展時,"distribution" 一詞相當精確,就是把程式碼儲存到磁帶機中,抱著那一卷又一卷包含 BSD 的磁帶,拿到其他實驗室或學術機構,不過現在考慮的議題就複雜許多,光是網路傳輸與資料分享的方式早已提出無數的模型與對應的軟體建設,而且 GPL 也廣泛的應用到非 source code 的領域,像是文件、artwork,甚至 EDA 原始設計等等。GPLv3 本身必須相當明確的指出適用範圍與對象,同時也必須針對「衍生物」的「產生」途徑,做出基本的定義,用詞的改變可說是作一回應。
  • Web Application 或是 server-side 的應用
      這是另一個有趣的議題,在我們對 GPL 的認知上,如果我們要 re-distribute 以某個以 GPL 發行的軟體時,必須將衍生創作施加同為 GPL 的發行授權,但對於 server-side 的應用,是否可能完全不符合 "re-distribute" 的條件呢?有可能,但是,相當明顯的,這樣的案例非常多,要釐清問題點,所以提出 "Requiring Source for Web Applications"。
應該還可以多列出幾項,不過我看這些法律性的資料,伴隨不少詭辯,讓我又頭暈,到此先打住。
由 jserv 發表於 01:07 AM | 迴響 (0)

January 17, 2006

Cairo 練習:入力娘簡易實做

「入力娘」是輸入法框架一個相當重要的設計,事實上,輸入法不只是一個輔助輸入的程式,能夠發揮的空間太多了,如 vgod 兄曾撰寫 [輸入法框架帶來的無限可能],引述其中闡述輸入法的概念提示:
    輸入法的角色很特別,它位於一般應用程式和作業系統的中間。輸入法可以攔截所有程式的輸入,再加以轉換後輸出給應用程式。所以輸入法是一個非侵入式的輸入過濾器。以中文輸入法來看,就是攔截使用者從鍵盤輸入的一串字元,接著透過某種編碼(注音、倉頡…)轉換為中文字輸出給程式。輸入法一直以來都是扮演著這種輸入各國文字的角色,但輸入法真的只有這樣而已嗎?

    其實輸入法在作業系統中是一個可以攔截任何輸入的程式,我們可以在這個位置提供更多方便的功能,不只有打中文這麼單純的事而已。例如,當我們用英文輸入時,輸入法可以幫助我們較正拼字,也可以讓我們只輸入頭幾個字,接著就自動補齊剩餘的部分。甚至還可以作成網址輸入工具:當我們輸入「@台灣大學」時,輸入法就自動到google找出台灣大學的URL http://www.ntu.edu.tw,接著輸出 <a href=”http://www.ntu.edu.tw”>台灣大學</a>。
去年參加 ICOS 2005 (細節可參考 [ICOS 2005 落幕] 與 [ICOS 2005 見聞錄] 兩篇 blog),對 OpenVanilla 團隊精湛的演講與對開發輸入法系統的投入,印象深刻,其中也有「入力娘」的展示。

前幾天寫了 blog [拒絕注音文的小圖示],正巧今天花了一點時間學 [Cairo Graphics],所以就萌生念頭實做一個 Linux 版的「入力娘」:

這裡展示的技巧是 Alpha blending、cubic Bézier spline、antialiased text rendering,以及簡單的 transformation,目前已經可以把 [拒絕注音文的小圖示] 的圖示,動態的作透明度處理,並且施加 composition,挺有趣的 :-)
由 jserv 發表於 08:44 PM | 迴響 (4)

January 16, 2006

QEmacs hack

剛剛花了一點時間 hack [QEmacs],這個 QEmacs (簡稱 qe) 最大的特點就是 "Quick and Small",啟動速度真是沒話說,而且功能也很完整,至少我學過的基本 Emacs 指令都可以用,還有許多正宗 GNU Emcas 沒有的特性,不愧是 Fabrice Bellard 前輩的大作。我的 hack 主要是 Xft 的修正,因為在 cvs head 已經不能運作了,而且針對 UTF-8 也需要小量的修改,目前的成果如下:

以上展示用 QEmacs-hack 來編修網頁,而且是 WYSIWYG (What You See Is What You Get) 唷,看來我的 hack 已經快能正確運作了。

由 jserv 發表於 10:34 PM | 迴響 (0)

久病思起

從這個月 7 日開始,連續的感冒真讓我吃不消,濃痰 + 鼻塞 + 耳鳴 + 嘔吐 + 暈眩 + 久久的咳嗽,這一系列的生理警訊,只能用「多喝水、多休息」因應。除了零星寫了點文字、小小的 coding 量,大部分的時間都在休息與思考,今天複診又拿了一堆藥:

這兩週都在吃藥,稍微好轉又被交叉感染,真是有夠不舒服的,手頭還有很多計畫要作,而且目前生產力趨近零,這是午夜時常因而驚醒的惡夢,沒有生產力,那我還存在做什麼?

不過也難得可以好好的唸書,適才閱讀李清照的一闕詞,頗切合目前心境:
    攤破浣溪沙

    病起蕭蕭兩鬢華,臥看殘月上窗紗。
    豆蔻連梢煎熟水,莫分茶。
    枕上詩書閒處好,門前風景雨來佳。
    終日向人多醞藉,木犀花。
倚立綺窗前,一個人在家修養,手持書卷,倒也悠哉,也希望自己快能康復,畢竟過幾天又得「瘋狂 coding」了。
由 jserv 發表於 07:35 PM | 迴響 (1)

Orz-Linux

知名的繪圖軟體 GIMP 已經有十年歷史,最近繪製圖表與調整版面,常常使用 GIMP,而剛剛在 #dot 跟 pcman 聊到 "Debian for Beginners" 時,瞥見 [提案內容]:
    基本規格
    • 專案目標:用 debian 打造成適合初學者,具高度親和力的 distro
    • 最高指導原則:相容 debian,必須和自己安裝後手動調校的 debian 一樣
    • 基礎系統:使用 debian testing (必要時摻雜 unstable)
    • 套件庫:盡量使用 debian 官方套件庫,不足的以 apt.dot 補
    • 中文環境調校:預設 firefly 字型 & patch、反鋸齒調校、中文輸入法 (可更換)、粗體斜體
    • UTF-8環境:預設使用 zh_TW.UTF-8 locale,並能自動幫 /etc/fstab 加入正確的 codepage 和 iocahrset 設定
    [...後略...]
讓我腦中不禁浮現滿滿的 "Orz" 影像,畢竟,過去我們花了太多時間在「調校」(說「調教」我也不反對啦) Linux Desktop 了。不過,一旦調校完畢,Linux 就好像是自己的寵物,不忍釋手,過去的那些 "Orz" 呢?順手用 GIMP 改了一張圖:
是阿,這就是 Orz-Linux :-)
由 jserv 發表於 06:33 PM | 迴響 (1)

思索 C++

小時候,拜讀完 jjhou 前輩的大作《深入淺出 MFC》,並由書中的 MFClite 作延伸,做出類似 Borland Kylix 的 CLX framework,但是透過 Qt 來實做 GUI 的 classes。整個「移植」的工作大概從大學一年級開始,而在大二告一段落 (大約是我加入 Free Qt 的開發,不過沒多久,Trolltech 就以 GPL/QPL 釋出 Qt/X11),那個時候,我天真的以為自己懂 C++。長大後,一邊 trace g++,一邊讀 ISO C++ Standard,才知道過去是愚昧的,比井底之蛙還不如,這只能援用蘇格拉底的話:「我唯一所知的,就是我一無所知。」。

這幾天沒有體力 coding,就整理 bookmark、在床上思考。今天我又回到 C++ Programming 的議題,Mozilla 當初以 MPL (以及第三方授權) 釋出 source code 時,Mozilla.org 也整理許多相當重要的文件,其中 [C++ portability guide] 是相當經典的,很多專案都會有類似的文件,要求一定程度的可攜性,不過 Mozilla.org 這分文件很特別,因為當時 Netscape 被要求在二十種不同的平台運作,而 Mozilla 最核心的部份就是 XPCOM 與 NSPR,要跨越這麼多平台,勢必需要做出妥協,不僅需要為了 gcc 作 workaround,像是 SCO 或 HP-UX 這種系統,更是一大挑戰。

[C++ portability guide] 一文的共同維護者 Scott Collins 在 blog [ Writing Portable C++ ] 提到,他認為該文已經相當舊,多少不合時宜,引述他對於 C++ portability 的 看法:
    My only interest is in learning from the Mozilla team's experience in porting applications.

    Write standard C++, use the standard libraries, including Boost, require a modern compiler and conforming standard libraries before a platform can be considered a reasonable target (just say "No" to bad old platforms). Write less code because you use other portable libraries. If I can allow a little bias to creep in---if you really want to write portable/cross-platform apps: use Qt. Don't write your own database, use an existing one that's already portable. Don't write your own file-system interface, use an existing cross platform API as provided by Qt or Boost. Don't write your own object dispatch system. Don't create your own scripting language, insert an engine for Python, Javascript, Ruby, etc. Don't write your own XML parser, use a free portable implementation. Etc., etc.
這引來我高度的興趣,於是,我又回頭看 C++ 老爸列出的 [C++ Applications],許多知名的專案當然有羅列其中,我繼續思索 C++,從這些案例來看 guidelines。
由 jserv 發表於 06:21 PM | 迴響 (2)

Is Design Dead?

連續感冒一週,在家修養時閱讀了幾篇 Martin Fowler 大師的 [著作],在此之前我拜讀過他的經典著作《Refactoring : Improving the Design of Existing Code》,第一章影片出租系統的 Refactoring 案例,仍讓我記憶猶新。之前的 blog [鼯鼠與軟體專案開發] 略述個人在軟體專案開發的過程中,作為專案經理或架構設計者,總不免需要作個稱職的「鼯鼠」,特別設計所謂「消費性電子」的軟體架構,更是如此。

在我小時候,曾規劃些 J2EE 的軟體專案 (based on Jserv),除了 transaction 與 storage 的限制外,我可以明確說出軟體上的瓶頸與設計缺失,而如果是設計手機、PDA,或是其他手持裝置裡面的軟體架構,可就完全不是這回事。首先,基於價格或非技術的考量,可能使用根本不熟悉的硬體架構,也被迫作些高度 risky 的假設與評估,同時還要作硬體、baseband,或者 RF 的妥協,針對這些議題提出一狗票的 workaround,儘管最後作報告時,總是能畫出一系列漂亮的系統架構圖,然而,我們都知道,背後隱藏了難以計數修補的痕跡。

在我設計初期,僅可能透過 GoF 裡面經典的 23 個 Design Pattern,比方說我現在規劃的軟體架構中,使用了 Factory Method,其重要的概念就是讓提出一個(或一系列) Abstract Interface,讓 subclasses 決定該 instance-ize / initialized 哪些 classes,然而有許多非預期的因素涉入,看起來優雅的設計,被迫重複修改,把 "Dirty-hack" 嵌入,我遇過最有趣的例子就是設計 UI framework,結果原本理想的情況,竟然因為硬體的 backlight 考量而修改得面目全非。最近可能會花些時間思考 protocol / communication framework 與 software stack,果然我遇到不少來自 RF 的議題...

又,在時程不斷的壓縮、功能無止盡的要求,codebase 已經開始腐爛,本來是葡萄美酒的設計,現在則是酸溜溜的老醋,怎不叫設計者擔憂?(也難怪感冒一直沒好轉),該如何進行 Refactoring,就是相當重要的議題,Martin Fowler 大師的 [Is Design Dead?] 給予我頗多啟發,而 Ai92 做了簡體中文的翻譯 [設計已死?],可以加速我們閱讀的理解,對面大師的著作,不容我這個駑鈍者置喙,不過我到是想到一些有趣的議題。

Kent 提出的概念中,"Do The Simplest Thing that Could Possibly Work" 是相當重要的指導原則,對於許多要求 "Time-to-Market" 的專案 (老實說,我看到這個字,會不自覺的發抖),幾乎可以說僅可能把現有的 solution 強加組合,甚至執行者都靠著「自覺」完成基本的設計,而且,重點是根本就沒有一家廠商 (至少是可能的 partner) 能對該專案所需要的軟硬體技術有足夠的掌握能力,以工廠的思維進行下,會發生什麼後果,可想而知。在 Refactoring 的過程中,我們檢視了既有的問題,在資源較充分而且經驗也足夠的前提下,原本的「直覺」逐漸演化為「複雜但必要的設計」,這就如 Martin Fowler 在 [Is Design Dead?] 一文所說的 "What on Earth is Simplicity Anyway?"。

注意:以上僅是個人經驗,與目前任職的公司或工作團隊無直接關係,請勿自行臆測。
由 jserv 發表於 12:04 PM | 迴響 (1)

January 15, 2006

ubuntu - Linux for Animals

我常常在 Debian (sid) 與 Ubuntu 之間切換,不過看樣子,兩者的差異越來越大了,如果撇開這議題不論,剛剛發現 Ubuntu 一個相當有趣的描述,引用 [linux for animals] 的圖片:

而該 blog 的敘述提到:


    Welcome zee ubuntu… Only in linux… Come to linux, we’ve got ubuntu…
    Welcome zee coders… Only for linux… Got ubuntu and coders, only in linux…
    Forget windows!
    Linux, oh linux… Where the gnome is, and the packages!
    Linux, linux, linux!
    Linux, come to linux, can ya believe it?

Funny :-)

由 jserv 發表於 10:20 AM | 迴響 (0)

January 14, 2006

性向分析

剛剛瞥見 [性向測驗],索性玩玩看,正如分析結果告訴我們的:
    這只是眾多性向評量表之一,準不準確倒在其次,重要的是它可以讓你的生活更有趣味。
所以我基於趣味,張貼了分析結果:
  • 真實生活中你會被什麼性格的人吸引:
      馬 - 不可駕馭、自由浪漫的人最吸引你。
  • 在被追求的過程中,什麼方式讓你最無法抗拒:
      長頸鹿 - 有耐心、永遠不放棄。
  • 你最希望留給情人的印象:
      貓 - 有格調。
  • 你最不希望在何種情況下和情人分手:
      鱷 - 無情的、冷血。
  • 你希望和你的另一半建立何種關係:
      羊 - 好像心靈相通一樣,你們不需要語言,一個眼神或手勢就足夠了。
  • 你對感情世界腳踏兩條船的看法:
      人 - 你在乎社會的看法,婚後你不會有越軌的行為。
  • 你對婚姻生活的看法:
      獵豹 - 你一直想要婚姻,但是你一點也不瞭解婚姻。
  • 你對愛情的看法:
      鴿 - 你認為愛情是雙方面的承諾。
至於準不準呢?我目前沒有任何可驗證的對象,而且我的確不懂婚姻。
由 jserv 發表於 08:33 PM | 迴響 (0)

iterm/iiimcf 新年大進展

Mat 一放假,就急著告訴我 [IIIMCCF - IIIM Console Client Framework] 的新進展,腦際突然閃過「大躍進」的標語:
    土法煉鋼、超英趕美!
雖然這跟 Mat 的途徑沒有關係 (至少不是「土法」),不過「超英趕美」倒是真的,而且看起來相當不錯,引述 [ 沒圖沒真相] 的 screenshots:




目前的成果可以透過 svn 存取,希望在 2006 年能有新的突破,感謝 Mat 的付出!
由 jserv 發表於 03:59 PM | 迴響 (0)

我們都是這樣長大的

剛剛拜讀 TimHsu 兄的 blog [十三號星期五],不免引來會心一笑,是阿,我們都是這樣長大的,引用 TimHsu 兄的話語:
    十三號星期五

    今天的日子,總會令我不禁想起年少時狂熱追求電腦病毒技術的時代。
從高中二年級後,我就收手不作「壞事」(或者,應該說「研究」),沒想到,好快就十年了 *笑*。
由 jserv 發表於 03:48 PM | 迴響 (0)

偉哉 Opera

errr... 這裡的 "Opera" 不是歌劇,是而是挪威的 [Opera software],這家公司不需要我多介紹了,開發的一系列 Embedded Web browser,是業界響叮噹的重要解決方案來源,剛剛發現 Opera 在 GPE 也能運作了:

而最近關於 Opera 的報導可以參考: 偉哉 Opera!
由 jserv 發表於 03:29 PM | 迴響 (0)

January 13, 2006

glxsee : 用 OpenGL 撰寫的圖片瀏覽器

最近花了點時間寫書,目前的進度是 3D/OpenGL 圖形處理與 X Window System 的硬體加速機制,最近應該會撰寫些小型的 OpenGL、glitz、Cairo,以及 Xorz/Embedded 的應用程式作為範例。秀圖程式當然是不可或缺的,所以我做了 [glxsee],運作畫面如下:

直接把 README 檔案內容貼出來:
    glxsee is a picture viewer based on OpenGL.
    
    The dependency of glxsee contains GL, GLX, and GLib.
    To use, you can look up the messages from "glsee --help", and
    you can browse the pictures via cursor Up, Down, Left, and Down
    to move, and Enter key can be used to toggle the single picture
    and browsing mode.
    
    To adjust the screen resolution, you can modify the defintions in
    src/glsee-main.c :
    
      #define SCREEN_WIDTH 1024
      #define SCREEN_HEIGHT 768
    
    Have Fun!
    
下載 [glxsee] 這個只有 23 kb 的小玩具,主要作為 OpenGL 使用技巧的練習,歡迎指教,謝謝!
由 jserv 發表於 02:04 PM | 迴響 (0)

拒絕注音文的小圖示

剛剛 letoh 兄給了一個 link,讓我發現以下兩個很棒的小圖示:

分別顯示「注音文退散」與「斬殺注音文」。有時後會收到網友的來信,討論一些技術問題,這是好事,不過信件裡面不時會瞥見注音文字樣,然後八成就是作大學專題的... XD (時間有這麼趕嗎?就不能多打幾個注音,再來選個字?)。

看來下次回信可以貼張圖示 :P
由 jserv 發表於 01:04 AM | 迴響 (0)

January 12, 2006

每日一字: Flamer

b6s 兄很詳盡的為我們介紹了 "Flamer" 這個字,請參見 blog [荒謬大觀: Flamer],這裡引用之中的 [flamer 實例]:
    win32 0.2.5c的打錯字的crash問題已經過了很久了,網站上給人載的檔案卻一直還在?
    這種有問題的版本可以擺上來嗎?
    造成人家打文章打到一半當掉的損失是你們可以承擔的嗎?
    明明以前的版本沒問題那為甚麼不先把這個版本撤掉?
    要等到人家發現問題了換成舊版嗎?
    本來想更新的,但是看到版上一堆非常嚴重的瑕疵就讓我卻步了。 已經過了起碼三個月,我知道你們還在研討解決方案,但是也可以先把這個版本撤下來吧?
    酷音輸入法是個相當有發展性的程式,不過希望你們處理事情能積極點。
感謝網友提供真實案例,也感謝 b6s 兄的詳細講解。
由 jserv 發表於 11:44 PM | 迴響 (0)

Qt Library 的精簡

Qt Library 的精簡,如果真的要說,光是經驗分享絕對可以說上兩天,而如果要進行深入的測試,或者針對硬體平台的最佳化,絕對是相當程度的工作量。

為什麼呢?第一,Qt Framework 本來就有一定規模,藕斷絲連的錯綜關係,總令許多有心深入 Qt internal 的開發者,望之卻步,再者,Qt 是 C++ Framework,對於一些 critical 的環境來說,可能不是很合適,不過 Qt 設計的時候,考慮到平台相容性的議題,也因此,僅可能只用少量的 C++ 來實做,試問:我們要 C++ 的 virtual inheritance 做什麼呢?完整的 C++ RTTI 真的管用嗎?多數的 framework 還不自己作一套加強版或客製化的 RTTI 嗎?第三,Qt 實在是... (errr... 我發現這應該留在下次說,先保留一點神秘感)。

所以呢,Qt 的精簡絕對是相當重要的議題,這邊稍微整理一些提示: 前三者基本上是老生常談了,多數的 Qt Programmer 應該都很熟悉,至於「引入 GCC 新的 C++ visibility support」是怎麼一回事呢?參考 GCCWiki [Visibility],引述其中的重點項目:
    Why is the new C++ visibility support so useful?
    Put simply, it hides most of the ELF symbols which would have previously (and unnecessarily) been public. This means:
    • It very substantially improves load times of your DSO (Dynamic Shared Object).
    • It lets the optimiser produce better code.
    • It reduces the size of your DSO by 5-20%.
    • Much lower chance of symbol collision.
最重要的概念就是提供一個機制,讓 compilation process 很明確的知悉 ELF symbol 的 visibility,在 wiki page 已經有相當詳盡的解釋,提到這帶來的影響,恰好 Qt Library 就是可從中受益的典型。所以呢,在這個途徑中,我們要做的,就是適度的分析 Qt Library,並且允以區分 export / local symbol (TODO)。

Luciano Montanaro 跟我的討論提到以下的看法:
    Some of the visibility advantage can be obtained with ld-scripts, and actually building Qt with that hack is quite useful, but the shipped scripts have to be supplemented with some customizations.

由 jserv 發表於 11:30 PM | 迴響 (2)

Konqueror/Embedded for Qtopia 計畫開張

在 Konqueror/Embedded 的 mailing-list 讀到一則消息 [Project: Konqueror/Embedded for Qtopia],簡單來說,在德國的 [basysKom] 公司的資助下,正進行一個以 konqueror-embedded 3 branch 為出發、backport 到 Qt2/Qtopia 的新計畫,引用訊息如下:
    Here are the features we are going to implement until end of March are the following:
    • Port to Qt2 & Qtopia, as necessary fix font handling, encoding detection, alpha blending for Qt2
    • GUI framework for the special display design (640x240, landscape)
    • persistent cookies, accept all cookies automatically
    • tab-browsing (as multi-windows) and popup management
    • url line with history, persistent history
    • web search input line
    • security indicator
    • full screen mode
    • bookmark management
    • persistent self-signed SSL certificates
    • dialog for certificate management
    • proxy configuration dialog
    • image zooming
    • prefetching of scripts (delayed loading of images)
    • mimetypes & download manager
    • performance and stability improvements for IO scheduler (optimized for GPRS - many http requests in parallel)
看來真是令人振奮的消息。在我之前的 hacking Konqueror/Embedded 中,目標是希望在 Intel Xscale 平台運作的 Qtopia Phone Edition 有 Web Browser 的解決方案,當時控制 code size 在 3.3 Mb 以下,並且 SSL enabled 的前提,雖然成功運作:
不過 memory footprint 仍相當可觀,說不定未來有機會一起改進這個專案。

Happy Hacking!
由 jserv 發表於 10:02 PM | 迴響 (0)

真的理解 C 語言的 types 嗎?

拜讀葉博士的 blog [南柯一夢二十年],那句話總是徘徊於內心深處:
    遇到這樣的個案:
    • 第一堂課:「我有 20 年的工作經驗。」
    • 最後一堂:「現在我才發現,我只有 1 年的工作經驗,只不過重複了 20 年。」
    但願退休的那一天,我不會發出同樣的喟嘆。
從國中接觸 C 語言程式設計以來,我知道工具只是協助人們解決問題,重點還是在於如何去克服問題,陸續撰寫了中小型的軟體專案,也包含簡單的 C++ subset compiler,稍加閱讀 ANSI C Standard 後,曾有一度認為自己懂了 C 語言,然而長大後,才知道當時的無知與愚昧。

剛剛閱讀 Peter Seebach (ISO C committee) 撰寫的入門文章 [Everything you ever wanted to know about C types, Part 1: What's in a type?],裡面沒有艱澀的技術,只有我們熟悉的 C89/C99 Standard,然而,有些細節甚至讓我花了一段時間查證,我開始懷疑:
    「是否,我只有一個月的 Programming 經驗,只不過重複了好幾個月?」
該文從 C types 出發,先提及幾個經典的議題,像是 +/- sign 表示、補數表示、IEEE 浮點表示、在 C89/C99 中負值算術的差異與爭議處、極值表示、影響最佳化的 types、volatile / restrict qualifier,以及在 C 語言中實做資料封裝的概念,篇幅不長,但每個議題後面都可以找到許多引證與陷阱案例。舉例來說,文中提到 C99 中考慮到 compiler optimizations,在 "A new meaning for static" 提到以下的宣告:
    void foo(int a[static 16]);
vectorization 在近代的 compilation optimization 是很重要的議題,在之前的 blog [C-style 字串的最佳化] 可以發現 int a[] 的 object layout,而多數的指令集也提供了 16 (含以上) pipelines 的 SIMDs,有很大的最佳化空間。不過 C 語言的常見陷阱就是 array indexing 的範圍,是有高度的自由,當然,在特定的 C compiler 對此會作些規範,比方說 TI DSP core 專用的 compiler 就伴隨了許多描述用的語法,表示 Runtime 的 indexing 坐落範圍。

再來是經典的 volitile 與 restrict qualifier,這在多數的 interview 會考到,我甚至可以把 ISO C Standard 裡面的定義背出一部分,然而,我真的懂嗎?在開始 trace Linux kernel device driver 後,才發現 volitile 以及 GCC optimization 造成的影響是相當大的,而且會引來相當 tricky 的效應。打開 /usr/include/string.h 可以發現以下兩個宣告:
    __BEGIN_NAMESPACE_STD
    /* Copy N bytes of SRC to DEST.  */                                  
    extern void *memcpy (void *__restrict __dest,                
                         __const void *__restrict __src, size_t __n)
         __THROW __nonnull ((1, 2));                                     
    /* Copy N bytes of SRC to DEST, guaranteeing
       correct behavior for overlapping strings.  */                       
    extern void *memmove (void *__dest, __const void *__src, size_t __n)
         __THROW __nonnull ((1, 2));                                    
    __END_NAMESPACE_STD
    
memcpy(3) 與 memmove(3) 在語意上最大的差異,就是允許 overlap 與否,這是為何 C99 中,兩者引數有不同 prototype 的緣故。Peter Seebach 在這系列的文章尚有三篇,想必可引來更多的思索,在此同時,如果不想在工作二十年後自嘆「我只有 1 年的工作經驗,只不過重複了 20 年。」,還是多觀察案例,多作思索並動手作,自勉之!
由 jserv 發表於 06:01 PM | 迴響 (0)

是否 Code Review 的思索

剛剛拜讀了 [Why I don't believe in code review],作者以軟體設計師應該視同藝術家的角度,反思業界常見的 Code Review 制度,迴響的部份也很值得一讀。

由 jserv 發表於 04:06 PM | 迴響 (0)

Use the Source, Luke! (2)

之前的 blog [Linux - 原力與你同在] 與 [Use the Source, Luke!] 提到星際大戰與 Linux 吉祥物 Tux 的趣味比喻,而剛剛看 [Advantages of Free Software and Open Source in embedded systems] 簡報的第 12 頁,又瞥見類似的圖樣,摘錄如下:


Use the Source, Luke!

由 jserv 發表於 09:56 AM | 迴響 (0)

January 11, 2006

TOSSUG 跨年倒數程式

今年元旦,TOSSUG (Taipei Open Source Software User Group) 舉辦了跨年 party,詳細的紀錄可以參考 [ 跨年 party 圓滿結束了!],有朋友來信問及那個「倒數的動畫程式」可否提供下載?我已經很久沒有動過那隻程式,不過有興趣的朋友可以 [抓來玩],下載後,請確定您的平台有 OpenGL 與 SDL 的開發套件,運作的情況類似下圖:


滑鼠的左右 click 可以控制翻轉方向,再按一次定格。

Have Fun!

由 jserv 發表於 10:59 AM | 迴響 (0)

January 10, 2006

SPECjbb2005 新標準

剛剛在 David Dagastine 的 blog 看到 [SPECjbb2000 has finally retired],業界標準的 Java benchmarking 參考 SPECjbb2000 已經被 SPECjbb2005 取代,後者的特性,Dagastine 用以下文字表示:


    Gone are the days when a stunt JVM can make broad claims in world record performance based on a 5 year old benchmark. No more risky lock elision optimizations for 30% gains and special object ordering and prefetching because GC is outside the measurement intervals. Good riddance I say!

同時,某個 VM 從 SPECjbb2000 移轉到 SPECjbb2005 時,並沒有如預期的表現:

    Strangely, a particular JVM vendor who showed strong performance in SPECjbb2000 doesn‘t seem to do as well with SPECjbb2005. Hmmm.

由 jserv 發表於 09:16 PM | 迴響 (1)

Flirt - an open source, extensible Flash(tm) runtime

Macromedia (已被 Adobe 併購) Shockware Flash 引來許多創意的呈現,豐富了網路的風貌,但是 open source Flash player/renderer 還是受限於規格開放的不足。就目前的實做來說,做得最好的兩個 open source 計畫分別是 [GplFlash] 與 [SwfDec],前者有 gplflash-2 branch,目標是 Flash 7 規格的支援,成效也相當好,不僅有 ActionScript 的支援,也成功播放多個 Flash 動畫,不過 library dependency 也變多,目前依賴 OpenGL 與 FFmpeg,並且主體以 C++ 撰寫。而 SwfDec 較為輕巧,穩定性也夠,可惜對於 ActionScript 的支援不是很好,但額外提供了給 Gtk+ 與 GStreamer 的 plugin,對於軟體整合來說,做得比較好。

[flirt] 則是新起之秀,引用 README 內容:
    Flirt is an SWF rendering library. Flirt contains a parser for reading SWF format files, a rasterizer for rendering the vector shaped into bitmaps, and an actionscript engine. Just hook it up to a timer and you've got a player. Interface your system UI events into the hooks provided and it's interactive. Present your application code to the player as actionscript objects and you've got a scriptable, cross-platform UI.
以 GNU GPL 授權發行,實際測試後,發現功能與完成度相當高,SDL 的 test program 也才 235k,而 library dependency 有 libjpeg、libpng,以及 libmad (處理 Flash audio streaming,是 MP3 格式)。剛剛以紅樓夢的 Flash 動畫作測試 (來源: http://flash.sp169.com/flashmtv/honglou.swf ),運作畫面如下:

這個計畫看來很棒,有人想一起來 hacking 嗎? :-)
由 jserv 發表於 04:54 PM | 迴響 (6)

wmctrl - 對符合 EWMH 的 WM 傳送命令

上週參加 [KDE@Taiwan 第二次使用者聚會] 時,[LCamel] 兄問我一個問題,他希望能在程式中,讓 Window Manager (可能是 KDE 的 kwin 或 GNOME 的 metacity,甚至是其他 WM) 可以切換到 desktop,而非一堆 stacking window。關於 Window Manager 的問題一向可以扯出許多規格,不過這個需要要達成不難,參考 EWMH (FreeDesktop 對於 ICCCM 的延伸規格:[Extended Window Manager Hints]),許多先進的 Window Manager 都部份支援了,而透過 [wmctrl] 這隻小程式,可以遞送 hints 給 WM。

以下展示在 XFCE-4.4 (採用 xfwm-4) 下運作 wmctrl 的結果:
    jserv@venux:~$ wmctrl -m
    Name: Xfwm4
    Class: xfwm4
    PID: 2948
    Window manager's "showing the desktop" mode: ON
    jserv@venux:~$ wmctrl -l
    0x00e00003 -1 venux Task List
    0x0100005b -1 venux Xfce 面板
    0x01600003  2 venux XChat: jserv-- @ FreeNode / #dot (+n)
    0x01400066  0 venux freshmeat.net: Search results - +window +manager - Firefox
    0x01e00004  0 venux rxvt-unicode
    0x02400004  0 venux root@venux: /home/jserv/jhacker/classpath
    0x01200004  2 venux rxvt-unicode
    0x01800025  0 venux Liferea
    jserv@venux:~$ wmctrl -k on
    
首先,先透過 wmctl 查詢 window manager 的資訊,稍後列出被 xfwm-4 管理的 X11 Window (此處的 "Window" 乃 resource),最後,我們要求 window manager 切換到桌面模式。

補充:可參考 Kyle Rankin 的文章 [wmctrl -- Shade, move, resize windows from a shell]。
由 jserv 發表於 01:50 PM | 迴響 (0)

我不在家就在咖啡館,我不在咖啡館就在去咖啡館的路上

剛剛隨性閱讀一篇 blog [我不在XX,就在去XX的路上],總覺得這個 "pattern" (well,似乎有些貶抑文學為 machine learning 層面的意味) 十分熟悉,記得去年才在誠品書店看過。回去翻了一下,原句應該是:
    「我不在家就在咖啡館,我不在咖啡館就在去咖啡館的路上。」
這是法國詩人 Honore de Balza 說的,不過 [eastecho] 這樣變化,也有些趣味。

延伸閱讀:
由 jserv 發表於 12:48 PM | 迴響 (1)

GNU Classpath 計畫與 Sun JDK 1.4 的相容度達到 98.12%

從 1998 年至今,GNU Classpath 匯集了全球許多開發者的投入,而在 2006 年的今天,與 Sun JDK 1.4 的相容度達到了 98.12%,在 Japi (用以測試相容度的開放套件,運作原理可參考我在去年 JavaTwo 的演講簡報 [Free Java Runtimes 簡報上線],裡頭也有對 GNU Classpath 與相關的 Free Java Runtimes 作簡介) 的分析報表指出:

(中間略)

至於詳細的分析報告,可參閱 [Results of comparison between jdk14 and classpath],同時也可以參考 Japi 的主要維護者 Stuart Ballard 的 blog [Merry Christmas and a Japi New Year],他提到:
    There are now only two packages red - entirely missing - in 1.4 (jpeg and kerberos), one orange (html - 48% implemented but with a lot of work being done right now by Anthony and Lillian) and two yellow - 80-90% (ldap and print).
    Against 1.2 the story is, as you would expect, even more impressive - only 0.74% missing, consisting of 9 classes (all in swing.text.html) and 10 methods (mostly in swing.text).
真是令人振奮!同時,GNU Classpath 也將有針對 Java Micro Edtion 的分支,而 Kaffe 下個版本 (1.1.7) 也會在近日釋出。

Happy GNU Year!
由 jserv 發表於 10:13 AM | 迴響 (0)

January 08, 2006

KMScript : 簡化繁瑣鍵盤與滑鼠操作的小程式

剛剛閱讀 qrttl 的 blog [KMScript誕生,the Keyboard and Mouse Script Language]後,覺得 qrttl 創作的 KMScript 很有趣,抓下來玩玩,運作的情況如下圖所示:

現在可以透過簡單的 script,自動執行那些繁瑣的鍵盤與滑鼠操作,這是透過 JDK 1.3 以後引入的 [class java.awt.Robot] 來實做,應該可以拯救許多替代役男吧 *笑*
程式下載方式可參考 [Robot's child],或者用 [我打包的 tarball],前者與後者的差異只在於,我拿掉了多餘且重複的檔案。 Have Fun!
由 jserv 發表於 10:13 PM | 迴響 (0)

Happy GNU Year

昨天紀錄 [KDE@Taiwan 第二次使用者聚會圓滿落幕] 時,想到我在 [KDE@Taiwan 第二次使用者聚會] 中,因為找不到 KDE@Taiwan 的正式 logo (以前有個 KDE 圖樣加上 ROC 國旗的,不過後來沒在用),隨性用台灣空拍圖加上 KDE 官方 logo,就塞到 [淺談 KParts、XParts,以及 GParts 與桌面整合技術] 的 slides 中。沒想到,今天閱讀 Yurenju 的 blog,發現他已經做好 [KDE@Taiwan logo (非官方)]:

真是感謝,如果能夠更精確的指明是 "KDE Taiwan",應該就更好了。

hosting 許多 GNU / non-GNU 計畫的 Savannan 網站也在新年跟許多朋友問好,引用其中一張圖來拜年:

(來源: http://savannah.gnu.org/images/floating.png )

希望在 2006 年,自己的各項計畫能夠順利進行,並學些新知識,Happy GNU Year!
由 jserv 發表於 09:09 PM | 迴響 (1)

憑弔周恩來總理 -- 仙逝三十週年

先聲明,我不是中國共產黨員,更非具備這樣的資格,只是簡單地對歷史人物作憑弔。

中國「文化大革命」的邁入尾聲之際,周恩來與夫人鄧穎超決定離開人世後,要把遺體火化,並將骨灰撒在祖國的土地上。下午再次閱讀《中國共產黨史》時,在周恩來總理仙逝三十年後的今天,不經意想起《古詩十九首》的第十四首:
    去者日以疏,生者日已親。
    出郭門直視,但見丘與墳。
    古墓犁為田,松柏摧為薪。
    白楊多悲風,蕭蕭愁殺人!
    思還故里閭,欲歸道無因。
    
乍看是遊子離鄉背井,在城郊看到荒廢的墓塚,有感在生死大限,抒發世亂懷而不可得的愴痛,而三十年前總理的病歿,讓我對這首前兩句「去者日以疏,生者日已親」,有很深的體悟。天地,猶如萬物的逆旅;人生,猶如百代的過客,死去的人歲月長了,昔往的印象逐漸模糊,甚至隨時間淡滅,作為一個新生者,我難以想像三十年前的事件,那段在我尚未展開人生歷程的一切。接受台灣教育成長,身處於倉粟小島,被強行灌輸「中國人的驕傲」與研習從未徹底屬於中華民國疆土的「秋海棠」,這些「善意的謊言」在許多年後,我才知道主政者的「用心」。或許如此,對於許多歷史事件是盲目的,我能夠說出漢唐盛世的許多人物的生平事蹟,但對於如此切近我生存年代的中國近代史,卻如此的茫然,新中國 (為了避免誤會,只要是武昌起義或共產革命建立的政權,我都認同是「新的」中國,這裡取簡稱) 的變動,在我的記憶所及,除了八年抗戰、國共分裂、國民黨在台的建設,以及擠身亞洲四小龍外,竟然說不出更具體更切合先列先賢用鮮血建設的一切?!

《古詩十九首》之十四引來的思考,正如《蘭亭集序》中的「昔之視今,亦猶今之視昔」,今日之「去」,曾有過往昔之「來」,而今日之「來」,豈非有來日之「去」?人生如寄,一「去」一「來」中歲月消逝得如此迅速,那麼長期作客的遊子,如吾輩,又如何能不為之怵目驚心呢?試著揣摩漢代無名詩人的心境,凝視著滿眼丘墳,冥索人生,原本死板的歷史文獻,對我而言,又有新的生命,是的,人類的歷史進程,不也是這樣的遞移循環呢?

1976 年一月八日,中共建國二十七年來,一直擔任總理職務的周恩來死於癌症,而巨大的中國歷史變動,可說是在這個年份揭竿而起。該年六月,朱德辭世,九月毛澤東主席逝世,隨後四人幫垮台,民運與自我意識的覺醒,邁入新的里程碑,而光是這一年,受逮捕、死傷,以及失蹤者,不計其數。自從周恩來總理在一月八日病歿後,人民陷入悲痛的低潮不已,客觀來說,與其是痛悼總理,不如說是自憐,對未來命運的不確定性感到無奈,踏在新中國的土地上,忐忑的人們不啻如《古詩十九首》之十四所描述的「白楊多悲風,蕭蕭愁殺人!思還故里閭,欲歸道無因。」?作為一個最佳戰友,周恩來之於毛澤東,就如恩格斯之於馬克思,在那動盪不安的年代,周恩來總理協助了毛主席掃蕩了許多「叛徒、內奸、工賊、走資派」,唉,背後不僅僅是幾個家庭的破碎,更是一個接著一個的人間悲劇,但作為國家總理,周恩來的確相當用心,而且八面玲瓏地處理國內與新中國的國際問題,也對於毛主席許多倒行逆施的政策,達到制衡的效果,也因此,周恩來總理辭世後,經常有人在天安門廣場中央的英雄紀念碑,哀悼這位「人民的好總理」。

在中國人傳統中,四月五日是清明節,無論工作是如何繁忙,總要祭祖掃墓,對往生者表示追憶,作為新中國的「過客」,緬懷周總理就等同於對過去的安定有所希冀,在同年的四月一日清晨開始,越來越多的人捧著花圈來到天安門英雄紀念碑。在當時主政的四人幫的眼中,群眾的聚集往往是造反的導火線,許多民兵被派遣來「督導」,並在晚上沒收民眾追思的花圈,於是獻花的民眾乾脆守在紀念碑前,不捨離去,甚至還有許多學生加入聲援的行列。很快的,四月四日當天,整個天安門廣場聚集了滿滿的花圈、人海,當然還有人民的怒火,「文化大革命」對整個中國的政經、文化,甚至思想發展,造成難以磨滅的高度破壞,而四人幫的禍國殃民,更是令人民所不齒,是此,一系列的衝突爆發了... 這段歷史的細節,先行略過,可以想見的是,「殺人如麻」早已無法形容那樣的悲劇,事後當然是大肆封鎖,而少數尚存的照片拍攝到人民對暴政的怒怨,在布條上寫道:
    「欲悲聞鬼叫,我哭豺狼笑,灑淚祭雄傑,揚眉劍出鞘!
    秦始皇的暴君時代過去了,中國人民再不是愚不可及的」
    
「天安門事件」的真相,至今尚未全部公開,只能拼湊片段的記憶,的確,「昔之視今,亦猶今之視昔」,今日之「去」,實在是過去這麼多鮮血與搏鬥的付出交換的「來」,為此,不勝唏噓。

周恩來總理原藉浙江紹興,1898 年三月五日生於江蘇淮安。1917 年在天津南開學校畢業後赴日本求學,開始接觸馬克思主義,思想發生重要轉折。1919 年回國,於九月進入南開大學,在五四運動中成為天津學生界的領導人,稍後 1921 年加入中國共產黨,在國共合作期間任廣東黃埔軍校政治部主任,國民革命軍第一軍政治部主任、第一軍副黨代表等職。1931年十二月,離開上海到中央革命根據地,先後任中央蘇區中央局書記、中國工農紅軍總政治委員兼第一方面軍總政治委員、中央革命軍事委員會副主席。1934 年十月加入「萬里大長征」,1935 年一月在貴州遵義舉行的中共中央政治局擴大會議上,對實際確立以毛澤東為代表的新的中央的正確領導,起了關鍵性的作用,並繼續被選為中央主要軍事領導人之一。1936 年十二月,張學良和楊虎成發動武力拘禁蔣介石的「西安事變」後,任中共全權代表與秦邦憲、葉劍英等去西安同蔣介石談判,和張、楊一起迫使蔣介石接受「停止內戰、一致抗日」的主張。

1961 到 1965 年間,為糾正「大躍進」帶來的失誤,扭轉經濟困難局面,他和劉少奇、鄧小平領導了國民經濟的調整工作,使國民經濟逐步得到恢復和發展。「文化大革命」期間,在非常困難的處境中,為儘量減少「文化大革命」所造成的損失,使黨和國家還能進行許多必要的工作,維持國民經濟建設。並且與林彪、江青集團進行了各種形式的鬥爭,在挫敗林彪、江青集團種種分裂和奪權陰謀活動中,起到了控制和穩定局勢的作用。1972 年,周恩來總理被診斷出患有膀胱癌,但仍任國家總理職務,一如昔往出席重大會議,如 1975 年的第四屆全國人民代表大會第一次會議。1976 年一月八日逝世。

以《訃告》為本文作結,並憑弔近代中國史:
    「周恩來同志,因患癌症,於一九七六年一月八日九時五十七分在北京逝世,終年七十八歲。」

參考資料:
由 jserv 發表於 07:53 PM | 迴響 (0)

January 07, 2006

How Do People See You?

Slow and Steady
Your friends see you as painstaking and fussy.

They see you as very cautious, extremely careful, a slow and steady plodder.

It'd really surprise them if you ever did something impulsively or on the spur of the moment.

They expect you to examine everything carefully from every angle and then usually decide against it.
How Do People See You?

由 jserv 發表於 09:00 PM | 迴響 (1)

KDE@Taiwan 第二次使用者聚會圓滿落幕

今天舉辦的 [KDE@Taiwan 第二次使用者聚會] 甫落幕,感謝各位朋友抽空於寒流來襲的日子,還能參與這個聚會。不同於去年嚴肅的主題,今年的地點在台北二二八和平紀念公園附近的 Starbucks 咖啡店 (後來因為場地限制,移師於怡客咖啡),而 #kde.tw 幾個熟面孔都來捧場,包含 KDE@Taiwan 的台柱 AceLan、永遠美麗的招待小姐 faifai、從新竹趕來的 kclin 與 lwhsu、葉平教授、cyt,睡過頭的 chihchun,以及來自中研院的 LCamel 兄。除了分享使用心得,大概也交流了一些工作上的趣聞。(可惜這次似乎沒聽到什麼八卦)

首先,AceLan 介紹了「KDE@Taiwan 現況報告」、「KDE-i18n 翻譯現況」,以及「Qt Quarterly正體中文翻譯現況」等三個大項目的現況,雖然 KDE 3.4 時繁體中文翻譯因為無法達到 KDE i18n 要求的水準而被 drop,不過 3.5 Release 時終於又有繁體中文了,同時,「Qt Quarterly正體中文翻譯」算是 KDE@Taiwan 領先全球許多 KDE User Group 的項目,甚至還受到來自對岸朋友的關注,也期望有更多新的進度。

Ping 教授稍後分享他以 Python 實做的線上翻譯協調系統,設計不是很複雜,但是看來挺實用,在翻譯者數量不多的時候,是可以很有效的協助完成翻譯並予以呈現。

連續感冒三天的我,很勉強地出席這次的聚會,不免頭重腳輕,而且聲音沙啞的分享了「淺談 KParts、XParts,以及 GParts 與桌面整合技術」(下載 [PDF slides]),中間有好長一段時間沒辦法發聲,希望與會的朋友看了 slides 能聽懂我當時分享的內容。

至於我這次分享的 Demo 以及我在設計 [kBrowser] 的一些改進 ([kBrowser] 是以 KDE/Konqueror 2.2 為基礎,針對 Embedded Systems 的 foorprint 與異質性 graphics toolkits 做了些調整,但是基本上,的確是使用了貨真價實的 KDE 元件技術),或許可以留在類似 [osdc.tw - Open Source Developers' Conference in Taiwan] 一類的會議,再來分享 (如果我有空,且完成 paperwork,而主辦單位不嫌棄的總總前提都成立的話)。

以上,再度感謝各位的參與和 AceLan 的籌備,也期待明年的盛會。

由 jserv 發表於 07:48 PM | 迴響 (0)

January 05, 2006

Chris Lanfear 的 blog

知名的 Ventrue Development Corporation (VDC) 的嵌入式軟體研究總監 Chris Lanfear 也有 blog -- [On Target: Embedded Systems],有許多針對 Embedded Systems 市場的分析與探討,值得關注。
由 jserv 發表於 01:23 PM | 迴響 (0)

January 04, 2006

Tk XIM 修正

一年多前,我試著修正 Tk 8.3 的 XIM 支援,而剛剛試著改 cvs head 的 Tk,初步看起來可以愉快的運作 SCIM (相信 gcin 或其他 XIM server 應該也沒問題才是)。使用方式先 check out cvs 的 tcl 與 tk:
    cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/tcl login 
    cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/tcl co -P tcl
    cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/tktoolkit login
    cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/tktoolkit co tk
    
依序建構 tcl 與 tk,並且使用 [tk-cvs-xim-fixes.diff] 這個修正。

用 aMSN 來作測試,畫面如下:

看起來挺不錯的 :-)
由 jserv 發表於 03:00 PM | 迴響 (5)

January 03, 2006

To which race of Middle Earth do you belong?

《Lord of the Rings》的世界令許多人著迷,[quizilla.com] 有個新的心理測驗 "To which race of Middle Earth do you belong?" ,我的結果是: 這份測驗的用詞對我而言挺難的,還是反覆查閱 Wikipedia 才知道問題與選項,而最終的結果 Numenorean,在 WIkipedia 上可參考 [Númenor]:
    Númenor is a fictional location from J. R. R. Tolkien's universe of Middle-earth and is intended to be his version of Atlantis. From the Quenya Númenórë: "West-land", which Tolkien translated as Westernesse (it was Anadûnê in the Númenórean language).
依據《Lord of the Rings》的說法,大多數 Numenorean 都喪生於一場多種族的戰役,只有 Elendil 這個王族中被視為異端分子者,帶領一批人乘船遁逃,回到 Middle-earth,和部份早先到達 Middle-earth 的 Numenorean 在 Middle-earth 西部建立了國家,這群新的 Numenorean 族群組合,也稱之為 Dunedain。
由 jserv 發表於 01:14 AM | 迴響 (0)

January 02, 2006

XOrg 7 的編譯與修改

X11R7 是個相當大的改變,不僅引入許多新的技術與 driver 修正,也是首次為模組化的樣貌。在 Ubuntu Dapper 中已經有 [XOrg] 7 的套件,而 check out source from cvs repository 的過程更有條理。自己打包 Xorg package 的方式不難,大致如下。

首先,要取得 debianized inforamtion:
    $ apt-get source xorg-server
    讀取套件清單中... 完成
    了解套件依存關係中... 完成
    需要下載 7968kB 的原始檔案。
    下載:1 http://archive.ubuntu.com dapper/main
    xorg-server 1:1.0.0-0ubuntu1 (dsc) [1791B]
    下載:2 http://archive.ubuntu.com dapper/main
    xorg-server 1:1.0.0-0ubuntu1 (tar) [7944kB]
    
取出裡面的 debian 目錄,然後依據 [XOrg] 網頁的指示,取出 xserver 的 source code:
    cvs -d :pserver:anoncvs@cvs.freedesktop.org:/cvs/xorg -z9 co xserver/xorg
然後,把剛剛的 debian/ 目錄放進去,作我們想要的修改,之後跑:
    dpkg-buildpackage -rfakeroot-sysv -uc -us -sa -D
這樣就快快樂樂的開始打包了,當然,記得把 libexa.so 加入 file list 中。運作的情況,就如 /var/log/Xorg.0.log 所示:
    (**) RADEON(0): Using EXA acceleration architecture
    (II) Loading sub module "exa"
    (II) LoadModule: "exa"
    (II) Loading /usr/lib/xorg/modules/libexa.so
    (II) Module exa: vendor="X.Org Foundation"
            compiled for 7.0.0, module version = 1.2.0
            ABI class: X.Org Video Driver, version 0.8
    
而這過程中,也讓我想到,之前在做 Xorz (一個玩具 X server 實做,詳情可參閱本 blog 其他 entries) 時,做了些 MMX minor optimizations,xorg cvs head 似乎還沒收錄,所以我動手提交了 [Bug#5478 - Use fbSolidFillmmx in the place of fbSolid] 到 FreeDesktop Bugzilla,重複上面的動作,一個又一個的 debian packages 就準備完畢。

Debian rules!
由 jserv 發表於 11:44 PM | 迴響 (0)