2009年9月30日 星期三

linux - 監控溫度(EX58-UD3R)


規格:
主機板: EX58-UD3R
CPU : i7 920

安裝:
brook@ubuntu:~$ sudo apt-install lm-sensors
brook@ubuntu:~$ sudo modprobe coretemp
brook@ubuntu:~$ sensors

錯誤排除:
brook@ubuntu:~$ sensors No sensors found! Make sure you loaded all the kernel drivers you need. Try sensors-detect to find out which these are. brook@ubuntu:~$ sudo modprobe coretemp 或者 brook@ubuntu:~$ sudo sensors-detect # sensors-detect revision 5249 (2008-05-11 22:56:25 +0200) This program will help you determine which kernel modules you need to load to use lm_sensors most effectively. It is generally safe and recommended to accept the default answers to all questions, unless you know what you're doing. We can start with probing for (PCI) I2C or SMBus adapters. ......
結果:

2009年9月29日 星期二

lvm設定步驟


1. 設定partition為LVM 2. 建立VG 3. 建立LV 4. formation LV




安裝已存在的LVM



2009年9月27日 星期日

linux - hlist


一樣在include/linux/list.h中,開宗明義的說Mostly useful for hash tables where the two pointer list head is too wastful,點出hlist為啥要有hlist_head和hlist_node了。
/* * Double linked lists with a single pointer list head. * Mostly useful for hash tables where the two pointer list head is * too wasteful. * You lose the ability to access the tail in O(1). */ struct hlist_head { struct hlist_node *first; }; struct hlist_node { struct hlist_node *next, **pprev; }; #define HLIST_HEAD_INIT { .first = NULL } #define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) static inline void INIT_HLIST_NODE(struct hlist_node *h) { h->next = NULL; h->pprev = NULL; } HLIST_HEAD_INIT()和HLIST_HEAD()用於未定義的變數,INIT_HLIST_HEAD()用於以定義的變數。

static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) { struct hlist_node *first = h->first; n->next = first; if (first) first->pprev = &n->next; h->first = n; n->pprev = &h->first; } /* next must be != NULL */ static inline void hlist_add_before(struct hlist_node *n, struct hlist_node *next) { n->pprev = next->pprev; n->next = next; next->pprev = &n->next; *(n->pprev) = n; } static inline void hlist_add_after(struct hlist_node *n, struct hlist_node *next) { next->next = n->next; n->next = next; next->pprev = &n->next; if(next->next) next->next->pprev = &next->next; } hlist_add_head()就很是很簡單的將n加到h的第一個node上。

hlist_add_after()是將next加到n的後面去,這裡新加入的node是next

hlist_add_before()是將n加到next的前面去,這裡新加入的node則是n


static inline void __hlist_del(struct hlist_node *n) { struct hlist_node *next = n->next; struct hlist_node **pprev = n->pprev; *pprev = next; if (next) next->pprev = pprev; } __hlist_del()就像__list_del()一樣,把要del的node的前後串起來。



2009年9月25日 星期五

linux - Memory Barrier


static inline void barrier(void) { asm volatile("": : : "memory"); } 格式 : __asm__(組合語言:輸出:輸入:修飾詞")
__volatile__ 代表這行指令(這些組合語言),不和前面的指令一起最佳化。
"memory" 告訴GCC這些組合語言會改變所有的RAM的資料。
因為沒組合語言,又告訴gcc所有RAM的內容都改變,所以這個memory barrier的效用,會讓這行之前被gcc所cache到暫存器的資料通通寫回RAM裡面,也告訴gcc會讓之後讀取RAM的資料,必須再從RAM裡讀取出來。

取自
http://october388.blogspot.com/2008/12/memory-barrier.html



2009年9月21日 星期一

linux之link list


linux的code算是經過高手中的高手淬煉過的精華,應該是每一個programmer朝聖取經的對象才是,所以,近日想由簡單的一些header file著手,先挑了link-list(linux/list.h)開始看起。list.h開頭就說明了這個檔案是Simple doubly linked list implementation。 struct list_head { struct list_head *next, *prev; }; #define LIST_HEAD_INIT(name) { &(name), &(name) } #define LIST_HEAD(name) \ struct list_head name = LIST_HEAD_INIT(name) static inline void INIT_LIST_HEAD(struct list_head *list) { list->next = list; list->prev = list; } struct list_head宣告兩個指向struct list_head的指標,這樣可以很general的對任何struct做link-list的動作,而list.h所提供的api也都是對struct list_head進行操作。 LIST_HEAD_INIT(name)是用於還沒有宣告的做init的動作,主要是將prev和next都指向自己。LIST_HEAD(name)其實和LIST_HEAD_INIT(name)差不多,也都是用來init link_head的。已經宣告過的則要使用INIT_LIST_HEAD(struct list_head *list)做init。 在list.h中有使用到一個重要的macro,container_of(ptr, type, member), /** * container_of cast a member of a structure out to the containing structure * @ptr: the pointer to the member. * @type: the type of the container struct this is embedded in. * @member: the name of the member within the struct. * */ #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) 而offsetof在C99的offsetof macro中有提到。所以container_of()就可以看出先宣告__mptr,其型態為傳進來的member,其值為傳進來的ptr,接著再扣除member所在的offset,就可以找到原本的頭了。 /* * Insert a new entry between two known consecutive entries. * * This is only for internal list manipulation where we know * the prev/next entries already! */ static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) { next->prev = new; new->next = next; new->prev = prev; prev->next = new; } /** * list_add - add a new entry * @new: new entry to be added * @head: list head to add it after * * Insert a new entry after the specified head. * This is good for implementing stacks. */ static inline void list_add(struct list_head *new, struct list_head *head) { __list_add(new, head, head->next); } /** * list_add_tail - add a new entry * @new: new entry to be added * @head: list head to add it before * * Insert a new entry before the specified head. * This is useful for implementing queues. */ static inline void list_add_tail(struct list_head *new, struct list_head *head) { __list_add(new, head->prev, head); } /* * Insert a new entry between two known consecutive entries. * * This is only for internal list manipulation where we know * the prev/next entries already! */ static inline void __list_add_rcu(struct list_head * new, struct list_head * prev, struct list_head * next) { new->next = next; new->prev = prev; smp_wmb(); next->prev = new; prev->next = new; } /** * list_add_rcu - add a new entry to rcu-protected list * @new: new entry to be added * @head: list head to add it after * * Insert a new entry after the specified head. * This is good for implementing stacks. * * The caller must take whatever precautions are necessary * (such as holding appropriate locks) to avoid racing * with another list-mutation primitive, such as list_add_rcu() * or list_del_rcu(), running on this same list. * However, it is perfectly legal to run concurrently with * the _rcu list-traversal primitives, such as * list_for_each_entry_rcu(). */ static inline void list_add_rcu(struct list_head *new, struct list_head *head) { __list_add_rcu(new, head, head->next); } /** * list_add_tail_rcu - add a new entry to rcu-protected list * @new: new entry to be added * @head: list head to add it before * * Insert a new entry before the specified head. * This is useful for implementing queues. * * The caller must take whatever precautions are necessary * (such as holding appropriate locks) to avoid racing * with another list-mutation primitive, such as list_add_tail_rcu() * or list_del_rcu(), running on this same list. * However, it is perfectly legal to run concurrently with * the _rcu list-traversal primitives, such as * list_for_each_entry_rcu(). */ static inline void list_add_tail_rcu(struct list_head *new, struct list_head *head) { __list_add_rcu(new, head->prev, head); } list_add_tail()可以想像把新的加到head的前面,就等於加到最後面了(因為是doubly linked list)。 /* * Delete a list entry by making the prev/next entries * point to each other. * * This is only for internal list manipulation where we know * the prev/next entries already! */ static inline void __list_del(struct list_head * prev, struct list_head * next) { next->prev = prev; prev->next = next; } /** * list_del - deletes entry from list. * @entry: the element to delete from the list. * Note: list_empty() on entry does not return true after this, the entry is * in an undefined state. */ static inline void list_del(struct list_head *entry) { __list_del(entry->prev, entry->next); entry->next = LIST_POISON1; entry->prev = LIST_POISON2; } 看到後面的delete就簡單了,先把自己的前後node接起來,接著再把自己的指標指向特殊位置(我的認知應該是給kernel debug用的特別位置),這樣就完成了delete的動作,所謂的delete並沒有真的是放記憶體唷。

西點軍校的第一條法則


西點軍校的第一條法則 --- 沒有任何藉口,在戰場上,只有兩種結果,消滅敵人,否則就是被敵人消滅。那些一開始找藉口的人肯定會被敵人消滅。而那些一開始就很努力,但最後沒有完成任務的士兵,一樣會被敵人消滅。在戰場上,不論你找到了什麼藉口,只要你沒有完成任務,最終還是要被消滅,即便你做了最大的努力。

2009年9月17日 星期四

extjs - 自訂vtype


內建的vtype有email、url、alpha、apphanum等等,不過內建的vtype可能不合我們使用,所以我們就需要自訂vtype。 我們必須定義vtype的value、mask、error message以及testing function:
  • xxxVal: 輸入內容的正規表示式。
  • xxxMask: 輸入的遮罩。
  • xxxText: 錯誤訊息。
Ext.onReady(function() {
    Ext.QuickTips.init();
    Ext.form.VTypes['portListVal'] = /^([0-9]+[,\-])*[0-9]+$/;
    Ext.form.VTypes['portListMask'] = /[0-9\-,]/;
    Ext.form.VTypes['portListText'] = 'Invalid Port List';
    Ext.form.VTypes['portList'] = function (v) {
        return Ext.form.VTypes['portListVal'].test(v);
    }

    var form = new Ext.FormPanel({
        renderTo: Ext.getBody(),
        frame: true,
        items: [{
            xtype: 'textfield',
            fieldLabel: 'txt',
            vtype: 'portList'
        }]
    });
});




2009年9月8日 星期二

extjs, ux - Managed iFrame


JavaScript算是被誤解蠻深的語言,很多人都認為JavaScript很容易,卻往往寫出一堆邏輯錯誤,但是功能符合的code,進而造成許多的memory leak,這點我也避免不了,於是就有人想到用iframe來解決,目前我在使用上確實幫我解決了不少memory leak的問題,所以,也安心的讓大家亂寫一通(即便他們很認真的寫還是寫得很亂)。
最簡單的iframe就是指定xtype和defaultSrc即可,而切換頁面則透過iframe的setSrc(url)。
Ext.onReady(function() {
  var viewport = new Ext.Viewport({
    renderTo: Ext.getBody(),
    layout: 'border',
    items: [{
      region: 'west',
      title: 'west',
      collapsible: true,
      width: 100,
      items: [{
        xtype: 'button',
        text: 'google',
        handler: function () {
          viewport.getComponent('center').setSrc('http://www.google.com');
        }
      },
      {
        xtype: 'button',
        text: 'nano chicken',
        handler: function () {
          viewport.getComponent('center').setSrc('http://www.blogger.com');
        }
      }]
    },
    {
      region: 'center',
      title: 'center',
      id : 'center',
      xtype: 'iframepanel',
      defaultSrc: 'http://www.blogger.com'
    }]
  });
});


這樣每一個iframe的網頁都是一個獨立的網頁,即便,parent頁面已經有include extjs了,iframe裡面的網頁如果有用到extjs,還是需要在include一次。
參考資料:
http://www.extjs.com/learn/Extension:ManagedIframe
http://www.extjs.com/forum/showthread.php?t=71961
http://code.google.com/p/managediframe/