2010年12月26日 星期日

atomic operation

所謂的atomic operation在這邊有說明
簡單來說一個 atomic operation 就是不會被打斷的操作
一般來說可以看成是組語的一道CPU指令
一個指令不是做完就是沒做 不會有做到一半的情形

而有時候看到 atomic 用來形容一個 function
就表示該 function 同一時間內只有一個 thread 可以進入
例如 linux 的 open system call

2010年12月20日 星期一

android boot process

1.power on and boot ROM code execution
    一開始可用的 ram 只有 internal ram
    電源 ok 時會從 boot ROM code 開始執行 這是在 CPU 硬體內建的 code
    boot ROM code 會偵測 boot media 中的 boot loader 並把它 load 到 internal ram 中
    跳到 boot loader 執行

2.boot loader
    boot loader 是用來設定及初始化 memory 並且 load kernel 到 memory 中
    boot loader first stage 一開始偵測並設定 external ram (boot loader 太大時就會分為兩份 1st stage boot loader 會塞到 MBR 中的前 446 bytes)
    設定完成便 load main boot loader(second stage boot loader) 到 external ram
    second stage boot loader 會設定 file system, memory, network support, 還有可能設定 low level memory protections and security options
    接著就從 boot media 中把 kernel load 到 ram 中
    load kernel 完成便跳到 kernel 執行

3.linux kernel
    kernel 設定系統要 run 起來一切所需的事情, interrupt controllers, memory protections, cache and scheduling
    等到 MMU and cache 初始化之後系統可以用 virtual memory 和 啟動 user space process
    kernel 去 system/core/init 下找 init process 並且啟動它成為第一個 user space process

4.init process
    init process 是系統裡所有 process 的祖先
    init process 會去找 init.rc 檔 這是一個 描述一些system service, file system, 或是參數的 script
    init process 去 parse init.rc 並且啟動 system service processes

5.Zygote and Dalvik
    Zygote 被 init process 啟動並且初始化 Dalvik VM

6.the system server
    system server 是系統中第一個跑起來的 java 元件
    他會啟動一些 android service 像是 telephony service 和 bluetooth
    啟動的 service 都寫在 system server 的 run method 裡面 system server 的 source code 就在 frameworks/base/service/java/com/android/server/SystemServer.java

7.boot complete
    一但 system server 跑起來而且系統 boot 完成就會有一個 broadcast action 叫做 ACTION_BOOT_COMPLETE
    在你的 application 中 register 要接收這個 broadcast 就可以在系統 boot 完成後啟動你自己的 service

資料來源:
http://www.androidenea.com/2009/06/android-boot-process-from-power-on.html

2010年12月16日 星期四

android 的 service

android 的 service 有分為兩類(這裡討論的不是在寫 android 應用程式時用的 service)
1. android service
2. native service
jollen 的 blog 還有 android1.net 都有說明

此外 android 在 booting 時會啟動一些 service
android 的啟動流程在這裡也講得很清楚
依照 init.rc 所寫 init process 啟動 service manager 和 zygote 之後
似乎還會啟動很多 native service (eq: dbus)
只是這些 service 應該 application 的開發者是完全不需要關心的

zygote 會啟動 system server
這裡可以看到 system server 是用 java 實做 run 在一個叫 system_process 的 process 裡
system server 首先載入 android_servers 這個 library (c++實做 code 在 frameworks/base/cmds/system_server/library/system_init.cpp)
然後用 init1() 這個 jni method 去呼叫 system_init() 函式
system_init() 函式會啟動一些 native service 然後呼叫 system server 的 init2() 函式
init2() 函式接著啟動 android service 例如 power manager  window manager
這張圖可以看到 被 init2() 函式啟動的 android service 都是 run 在 system_process 中的一條 thread 裡

2010年11月23日 星期二

android 的 user space HAL

網路上一個有關user space HAL的問題
Q:
Hi All,

  I would like to know if there is any documents or related web links
for device driver development on "User Space Abstraction Layer ".
  I would appreciate if anyone can give me how this really works in
real world scenario.

 Thanks...

A:
I would suggest you to have a look of the overlay code in
hardware/libhardware/moudule/overlay.
In the new HAL architecutre, it introduced a "stub" concept which replaced
the legacy architecture which load the c/c++ library from java
application/service directly. In "stub", you need to implement some
interfaces and provide them to hardware service. For example if you wanna
implement a LED, the architecture will be:
Kernel Driver (driver to control the LED hardware) <-> syscall (open, close,
ioctl for LED, etc.) <-> hardware/libhardware/module/led (the led HAL
interfaces or "stub" ) <-> framework/base/services/jni/
com_android_server_LedService.cpp (the java native interface for LED )<->
framework/base/service/java/com/android/server/LedService.java (the java
interface of LED service <-> framwork/base/core/java
/android/hardware/LedManager (the java code of LED manager) and
ILedService.aidl (the android interface description language file for LED)
<-> LED application

這裡有一個文章連結

jollen的blog也有相關介紹文章

2010年11月16日 星期二

android 的 local service 與 thread 的差別

android 官網中提到要執行 background 的 long running 動作時 最好要用 service
但是 service 既然也是在同一個 process 中 create 一個 thread 來做這些 long running 的動作
為什麼不直接在 activity 裡直接 create thread 來做就好了

官網最下面有解答
1.
    一個有 service 在跑的 process 權限會比只有 background activity 在跑的 process高
    也就是當系統要砍 process 的時候比較不容易砍到你

2.
    用 service 的話 不管 activity 發生什麼事 都不會影響到 service, process 最少可以是 "service process" priority

android的application component是run在哪個thread

依照 android 官網所說 android 的 application component 包括 activity service broadcast receiver 等等
都是 run 在同一個 linux process 之中(除非這些 component 有特別指名要 run 在其他 process, 可以在 androidmanifest.xml 中指定)

官網又有說到 所有這些 component object 的實例化都發生在 process 的 main thread 中
而且有關 life cycle 的 method (例如 onCreate) 也都是在 main thread 中執行
所以在這些 method 中不能執行太花費時間的動作 免得阻擋到其他 component 的執行
如果需要作這些動作 應該 create 其他 thread 來做

2010年11月7日 星期日

vim 的自動完成

vim 也可以有自動完成的功能
在ubuntu 10.04下面裝的 vim 7 有預設支援自動完成的語言的資訊在 /usr/share/vim/vim72/autoload/ 下面

以php 為例 要開啟 php 自動完成功能 只要在 .vimrc 裡加上一行
    autocmd FileType php set omnifunc=phpcomplete#CompletePHP
就可以了

接下來在編輯 php 檔案時 只要用 ctrl+x ctrl+o 就可以使用自動完成

但是我最需要的 C/C++ 語言似乎需要額外的套件支援才能使用自動完成

C 的話有關鍵字自動完成可以用 不用在 .vimrc 中設定任何選項
只要在編輯 c 檔案時有 include 任何標頭檔 例如 stdio.h
在打入 print 時按下 ctrl+p 就會從 stdio.h 中找出符合的函式供你挑選

C++的話就沒有了 完全需要額外套件的支援
不知道為什麼 vim 不預設支援標準函式庫的自動完成 明明這是最需要的
關於 C/C++ 的自動完成之後再研究

2010年10月2日 星期六

vbscript 物件的解構函式不會在頁面關閉時呼叫

在VBScript裡面 可以寫下你自己物件的建構函式與解構函式
但是必須了解的一件事是 如果VBScript是跑在一個網頁上 網頁關閉時不會呼叫VBScript的解構函式
我本來以為 頁面關閉 物件銷毀 解構函式應該會執行 但是事實並不是如此
不過還好 還有 window.onbeforeunload 事件可以用
還是有機會在頁面結束前 作一些你想要執行的動作的

2010年10月1日 星期五

css 的 width 和 height 用百分比表示

在 css 裡面 元素的 width 和 height 可以用百分比表示
代表這個元素的寬和高為父元素的百分比
但是因為是使用父元素的寬和高來當基準 一定要確定父元素的寬和高也正確的設定了
否則可能會出現排版亂掉的情況

VBScript 和 JavaScript 的 string 是 pass by reference

在寫 scripting language 時 都知道變數通常可分為 primitive type 跟 reference type
primitive type 是 pass by value 而 reference type 是 pass by reference
可能語言會宣稱自己只有 pass by value (例如 java, 雖然他不是 scripting 語言)
但是保持一個觀念就是 reference type 的變數被傳進一個函式後
函式對這個變數做的改變在函式退出後還可以看的到

不過對 javascript 和 vbscript 來說 string 是特別的 string 不是物件 所以他是 primitive type
但是 string 又可以是任意長度的 所以如果 string 如果是 pass by value 將會很沒有效率
所以在實作上通常把他作為 pass by reference

如果只用 primitive type 和 reference type 來 分別 pass by value 和 pass by reference
可能會對 string 的 pass rule 搞錯了

2010年9月29日 星期三

vbscript default method 和 default property

在VBScript裡面的class可以有所謂 default method 和 default property 他的作用是可以讓人不需要用 method name 或 property name 就可以呼叫
此外一個class 只能有一個 default method 和 default property 否則會造成錯誤

如以下例子為 default method

class FOO
    public default function no_name
        msgbox "default function called"
        no_name = "i am FOO"
    end function
end class

dim o : set o = new FOO
msgbox o()
  
以上的程式會跳出兩個msgbox 可以得知 no_name 在執行到 o() 時被呼叫

在VBScript 裡面的 dictionary 還有 collection 物件都有 default property
collection 和 dictionary 的 default property 就是 Item property
可以讓人在 coding 時方便許多
例如 要在 dictionary 取一個 key 是 "kerker" 的 value
嚴謹的寫法是 dict.Item("kerker")
但是因為 default property 的關係 用 dict("kerker") 也可以 這樣用起來就方便多了

不過網路上關於 VBScript 的 default method, default property資料好像蠻少的 而且有人說最好不要用這個特性
因為這樣會讓寫出來的code 難以閱讀

2010年9月27日 星期一

Scripting.Dictionary

在 VBScript 或是 Jscript 中有一個很好用的物件叫做Scripting.Dictionary
他就像是 C++ 的 map, PHP 的 array 是一個關聯陣列 (不過Jscript的物件已經可以當關聯陣列用了 所以這個物件對Jscript不太需要)

這個物件有一個很好的特性 就是他的 Items() 和 Keys() method 傳回的陣列元素的順序就是元素加入物件時的先後順序
利用這個特性 用這個物件實做出像是 Stack 或是 Queue 就非常容易了

並沒有任何公開文件聲明Scripting.Dictionary物件必須維持此特性 只能說這是Scripting.Dictionary內部資料結構的實作造成這個事實
雖然依賴這種未公開特性去寫code有風險 只要微軟改變這個物件的實作 就可以讓這一性質消失
但是我覺得微軟應該不會再對Scripting.Dictionary有什麼變動了 沒有這個必要 VBScript 也不是微軟的焦點
所以如果有需要 就用這個特性寫下去吧  畢竟要自己實作 Stack 或是 Queue 太麻煩了

2010年9月24日 星期五

利用adodb.stream作編碼轉換

會知道adodb.stream有這個功能是因為我用winhttprequest物件去要求網頁時
該網頁回傳的是用 big-5 編碼的網頁 導致我出現亂碼
接著我上網搜尋在 vbscript 中作編碼轉換的資料 於是發現 adodb.stream 有這種功能

如以下例子

dim http : set http = createobject("WinHttp.WinHttpRequest.5.1")
http.Open "http://some_big-5_page.html"
http.Send
http.WaitForResponse

msgbox http.ResponseText

Dim oStream : Set oStream = CreateObject("adodb.stream")
oStream.Type = 1                                       '以二進位方式操作
oStream.Mode = 3                                      '可同時進行讀寫
oStream.Open                                            '開啟物件
oStream.Write http.ResponseBody               '將 content 寫入物件內
oStream.Position = 0                                  '從頭開始
oStream.Type = 2                                       '以文字模式操作
oStream.Charset="Big5"                              '設定編碼方式
msgbox oStream.ReadText()

在這裡會發現第一次 跳出來的視窗有亂碼  但是第二次的視窗就正常了
adodb.stream很好很強大 而且它支援多種編碼 不只是big-5
真的很方便

2010年5月22日 星期六

XMLHttpRequest物件的setRequestHeader

似乎是因為安全上的考量  現在使用 XMLHttpRequest 物件的 setRequestHeader method 時
有許多的 header field 不能設定 referer 就是其中一個
假使用以下的code
//vbscript code
xmlhttp.open ...
xmlhttp.setRequestHeader "referer", "http://..."
xmlhttp.send

我用 MSXML2.XMLHTTP.3.0 測試過了
用 sniffer 看實際送出的封包 會發現 referer 並沒有被加到 http header 中

上網找了資料 似乎 firefox safari 都有做這樣的保護措施
不過不知道為什麼好像資料很少  連 msdn 上面的 xmlhttprequest 物件說明也沒有註明這件事
就因為這樣害我找了好久的 bug = =

2010年4月3日 星期六

long long int

最近寫 acm 很常需要用到較大的數字 int 有時不敷使用
因此有用到了 long long int 這個型別
這個型別大小為 8 byte  在 C99 標準中有定義

scanf 或是 printf 系列函式用到這個型別時 要用 %lld 來表示

之前沒查資料  直接用 %ld 結果程式跑出來結果錯誤
寫 c/c++ 果然需要嚴謹一點才行

2010年3月28日 星期日

vbscript colon

在 vbscript 中 可以用冒號 ":" 來在一行中執行多個 statement

例如:

dim a : a=1

或者是
dim a, b, c
a=1 : b=2 : c=3

算是一個蠻好用的小知識

cmd /k /?

在cmd.exe下 鍵入 command /? 就會顯示出該 command 的參數說明
而 cmd.exe 的 /k 參數就是啟動 cmd 後執行跟在 /k 後的指令 並且保留命令視窗

若要在一行中執行多個指令 則指令間需要用 "&" 隔開