Tuesday, August 14, 2012

RW 4.2 Mint Choco

RW 透過攔截Linux硬碟讀寫,將讀寫資料緩衝在高速儲存裝置(目前是記憶體),提升系統效能。

RW 4.2 Mint Choco 實現以下功能:
  1. 將系統讀寫過的硬碟資料緩衝在記憶體
  2. 關機時將緩衝資料寫回硬碟
  3. 每10分鐘會掃描緩衝的資料,把很少存取的資料寫回硬碟並釋放記憶體
我把 ArchLinux x64 + Gnome 3 裝在普通USB2.0隨身碟上,並載入 RW 進行測試,實際使用的效果相當不錯,常常測試完就懶的回去用原本的OS了。(其實是因為 Gnome 3.5 比 我原本OS的 awesome wm 好看多了...)

平常使用記憶體大概用掉2G,不過Chrome本身就用掉1G... (Chrome吃記憶體真是太可怕了)

風險和問題:
  1. 目前只在 ArchLinux x64 測試過,不確定是否能在 32bit OS 運作。
  2. 這版還在測試階段,所以只支援緩衝一顆硬碟。而且沒有容錯機制,所以請隨時注意記憶體剩餘量
  3. 還未提供保護機制,如果系統非正常關閉,有很大機會導致檔案系統毀損。(重開機時 fsck 可能可以修復,不過應該會有資料遺失)
RW Mint Choco下載: https://github.com/pzread/rw/tarball/mint-choco
編譯與安裝說明在檔案 INSTALL

fio 512MB隨機讀寫跟512MB循序讀寫測試: https://github.com/pzread/rw/blob/mint-choco/testdata/result
























Saturday, August 11, 2012

拼音輸入法

今天試了一下Linux下的拼音輸入法,一開始用 Google拼音輸入法,後來改用 ibus-pinyin。自動選字都比原來的新酷音好很多,不過對拼音輸入法拼音方式十分不熟悉。



Monday, August 6, 2012

Linux Driver打印資料到螢幕上

雖然有 printk , pr_alert 等函式可以把一些debug資料打印到螢幕跟log檔中,但是用起來總是不太方便(前面都會被加上打印的時間之類的)。

所以試著直接open tty設備,write資料到tty上,沒想到真的成功把資料打印在螢幕上。

PS. 打印資料到螢幕上應該是由User Mode程式來做才對,不過某些狀況就是不太允許這麼做 (ex. 正在關機時)


















Code:
struct file *tty;
mm_segment_t old_fs;

tty = filp_open("/dev/pts/0",O_RDWR,0);
//顯示在XWindows下的terminal所以用 /dev/pts/0 ,如果是一般文字界面下用 /dev/tty0

old_fs = set_fs(KERNEL_DS);

tty->f_op->write(tty,"Hello Screen!\n",strlen("Hello Screen!\n"),NULL);

set_fs(old_fs);
filp_close(tty,0);

Sunday, August 5, 2012

rw 硬碟讀寫緩衝展示

"rw" 利用Hook的方式,不需要重新編譯Kernel就可以提供記憶體緩衝硬碟讀寫功能,增加Linux執行速度。目前有一些問題尚未解決。

圖中測試環境是在安裝在USB 2.0一般隨身碟上的Linux,連續或隨機讀寫速度都超過200MB/s。



Tuesday, July 31, 2012

維基大典

剛剛才發現維基百科有文言版。電子在文言中稱作"子"嗎?


電晶體


電晶體者,電子儀器之本也。蓋西方有人自沙中煉藥,曰為硅。硅有十四子,其外圍有四,與別硅扣環,求其穩定。後西人於硅中參入磷,使其多一子,曰為負型;或參入硼,使其少一子,曰為正型。 後人以兩負型中夾以少量正型,或兩正型中夾以少量負型而用。其外觀如水晶,故名為電晶,取電之晶體也。 電晶有三極,名曰集基射。若以基輸以訊,射接於地,集接於電,可於集取得數倍於基之訊,故可取訊之放大效果也。 或以集輸以電,射接於地,基輸以是,可於射取得否。數電晶相乘,可判是非也。

http://zh-classical.wikipedia.org/wiki/%E9%9B%BB%E6%99%B6%E9%AB%94

Sunday, July 22, 2012

dmenu_wrapper 把dmenu候選按照使用頻率排序

dmenu 是一個輕量級的程式執行器,可以快速找尋你想執行的程式。

網路上其實有不少它的wrapper,可以讓 dmenu 顯示的候選選項按照被選到的頻率排序。不過一直找不到適合的來使用(如 Yeganesh  是用 Haskell 寫的,Haskell套件有點大),所以最後決定自己寫一個。


 
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<errno.h>
#include<dirent.h>
#include<limits.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<map>
#include<algorithm>
#include<string>

using namespace std;

char log[PATH_MAX + 1];
char path[65536];
char out[67108864 + 1];
char name[NAME_MAX + 1];
char tmp[4096];
map<string,int> dic;
pair<string,int> lis[262144];

bool cmp(const pair<string,int> &a,const pair<string,int> &b){
    if(a.second == b.second){
        return a.first < b.first;
    }
    return a.second > b.second;
}

int main(int argc,char **argv){
    int i;

    FILE *f;
    int prio;
    char *ptr;
    int fd;
    DIR *dir;
    struct dirent *dirent;
    struct dirent *result;
    struct stat st;
    map<string,int>::iterator it;
    int count;
    char *last;
    FILE *pipe;

    sprintf(log,"%s/.dmenu_wrapper_log",getenv("HOME"));
    if((f = fopen(log,"r")) != NULL){
        while(fgets(name,NAME_MAX,f)){
            name[strlen(name) - 1] = '\0';
            fgets(tmp,4096,f);
            sscanf(tmp,"%d",&prio);
            dic.insert(pair<string,int>(name,prio));
        }
        fclose(f);
    }

    dirent = (struct dirent*)malloc(sizeof(struct dirent) + NAME_MAX + 1);
    strcpy(path,getenv("PATH"));
    ptr = strtok(path,":");
    count = 0;
    while(ptr != NULL){
        fd = open(ptr,O_RDONLY);
        dir = fdopendir(fd);
        while(true){
            readdir_r(dir,dirent,&result);
            if(result == NULL){
                break;
            }
            fstatat(fd,result->d_name,&st,0);
            if(!S_ISREG(st.st_mode) || !(st.st_mode & S_IXUSR)){
                continue;
            }

            prio = 0;
            if((it = dic.find(result->d_name)) != dic.end()){
                prio = it->second;
            }
            lis[count] = pair<string,int>(result->d_name,prio);
            count++;
        }
        closedir(dir);

        ptr = strtok(NULL,":");
    }
    free(dirent);

    sort(lis,lis + count,cmp);
    strcpy(out,"echo -e \"");
    last = out + strlen(out);
    for(i = 0;i < count;i++){
        strcpy(last,lis[i].first.c_str());
        last += strlen(lis[i].first.c_str());
        strcpy(last,"\\n");
        last += 2;
    }
    last -= 2;
    strcpy(last,"\" | dmenu");
    last += strlen(last);
    for(i = 1;i < argc;i++){
        strcpy(last," \"");
        last += 2;
        strcpy(last,argv[i]);
        last += strlen(last);
        *last = '\"';
        last += 1;
    }

    pipe = popen(out,"r");
    name[0] = '\0';
    fgets(name,NAME_MAX,pipe);
    pclose(pipe);

    if(name[0] != '\0'){
        name[strlen(name) - 1] = '\0';
        
        if(fork() == 0){
            execlp(name,name,NULL);
        }

        it = dic.find(name);
        if(it != dic.end()){
            it->second++;
        }else{
            dic.insert(pair<string,int>(name,1));
        }

        if((f = fopen(log,"w")) != NULL){
            for(it = dic.begin();it != dic.end();it++){
                fprintf(f,"%s\n%d\n",it->first.c_str(),it->second);
            }
            fclose(f);
        }
    }

    return 0;
}
 

不能隨便將字串丟入strtok

雖然知道strtok會把傳入的字串切亂,剛剛還是把getenv("PATH")所取回的環境變數PATH丟進strtok,結果就發生奇怪的Bug

char *path;
char *ptr;

path = getenv("PATH");
ptr = strtok(path,":");
while(ptr != NULL){
    printf("%s\n",ptr);

    ptr = strtok(NULL,":");
}
//此程式的環境變數PATH已經被strtok切亂

execlp("ps","ps",NULL));
//execlp取到不正確的PATH,找不到ps這個程式