2010年9月27日 星期一

Reverse SSH Tunnel (反向 ssh 連線)

Gmail IMAP, SMTP, POP3 設定值

IMAP
  • imap.gmail.com
  • Port: 993
  • Use SSL: Yes
SMTP
  • smtp.gmail.com
  • Port for TLS/STARTTLS: 587
  • Port for SSL: 465
POP3
  • pop.gmail.com
  • Port: 995
  • Use SSL: Yes

Meld : Diff and merge tool.

Meld is a visual diff and merge tool. You can compare two or three files and edit them in place (diffs update dynamically). You can compare two or three folders and launch file comparisons. You can browse and view a working copy from popular version control systems such such as CVS, Subversion, Bazaar-ng and Mercurial. Look at the screenshots page for more detailed features.


Token-pasting operator(##) in C

我們都知道C語言define前端處理假指令用來定義變數、字串或幾行的原始碼(統稱為巨集, Macro)。
當某一巨集被定義為參數帶入之巨集, 我們最常用的就是把該參數當作變數或指標來使用,如下所示:
#define INC_IDX(val, size) (++val % size) -> 以參數為變數之值帶入此巨集
#define GET_DATA(ptr) (ptr->data) -> 以參數為指標帶入此巨集

然而,我們可以把巨集所帶入的參數當作為識別子(Token)的一部分,如下所示:


#include

int class_num = 9;
int class_stds = 10;

#define GET_MEMBER(postfix) class_ ## postfix

int main(void)
{
     printf("class_num: %d\n", GET_MEMBER(num));
     printf("class_stds: %d\n", GET_MEMBER(stds));
     return 0;
}


如上列所示,class_num可以經由GET_MEMBER巨集(帶入部份識別子, 也就是num)取得,此參數傳遞方法稱為Token-pasting operator,這是一個非常好用的方法, 提供給大家參考。

The Stringify Operator (#) in C

繼上次提到Token-pasting operator (##) in C文章後, 這次講一下在C語言define巨集參數使用的另一種方法, 在參數名稱前加一個#運算子, 此運算子代表所帶入的參數會被編譯器視為"字串", 所以#運算子又被稱為字串化運算子, 底下為一簡單的例子:


#define GET_RESULT(exp) printf(#exp "=%d\n", exp)

int main(void)
{
    GET_RESULT(3+2);
    return ;
}






2010年9月9日 星期四

IGMP Proxy

把 Linux 當 NAT 或 Router 用, 而且需要用 Multicast 時, 需裝 igmpproxy

/etc/igmpproxy.conf 設定很簡單, 只要三行就可以運作

quickleave (將 Client 送的 leave 封包轉送給 upstream)
phyint eth0 upstream (指定 upstream 的 interface)
phyint eth1 downstream (指定 downstream 的 interface)

若有額外的 Multicast Source Address, 再用 altnet 參數指定, 寫在 upstream 那行的下面.

igmpproxy 執行後, 會將 net.ipv4.conf.all.mc_forwarding 及 net.ipv4.conf.ethx.mc_forwarding 設為 1

2010年9月3日 星期五

Git常用命令

快捷命令设置


1.git config --global alias.st status
2.git config --global alias.ci commit
3.git config --global alias.co checkout
4.git config --global alias.br branch
5.git config --global alias.dc dcommit
6.git config --global alias.rb rebase

彩色交互界面


1.git config --global color.branch auto
2.git config --global color.diff auto
3.git config --global color.interactive auto
4.git config --global color.status auto

设置用户信息


1.git config --global user.name "jianingy"
2.git config --global user.email "detrox@gmail.com"

克隆新项目 pre(brush:bash). git clone git://gitorious.org/bamboo/mainline.git bamboo

设置远程仓库


1.# 添加(origin 为一个标示,可以随意更换)
2.git remote add origin git@gitorious.org:bamboo/mainline.git
3.# 删除
4.git remote remove origin

操作远程仓库


1.# 提交本地修改(将本地修改提交到远程的master分支
2.git push origin master
3.# 合并远程修改(将远程的master分支合并进来
4.git pull origin master
5.# 删除远程仓库里的分枝
6.git push :branch

基本操作


01.# 提交修改
02.git add /path/to/file
03.git commit -m reason
04.# 提交全部修改
05.git commit -a -m reason
06.# 创建本地分枝
07.git co -b branch_name
08.# 查看分枝
09.git branch
10.# 删除分枝
11.git branch -D branch_name
12.# 查看分支之间的差异
13.git diff master branch
14.# 查看最新版本和上一个版本的差异(一个^表示向前推进一个版本)
15.git diff HEAD HEAD^
16.# 查看状态
17.git status
18.# 合并分支
19.git pull . branch
20.# 销毁自己的修改
21.git reset --hard

与svn互操作

 

1.# 从subversion仓库中克隆
3.# 将本地修改提交到subversion仓库
4.git svn dcommit
5.# 导入新的subversion更新

2010年9月2日 星期四

Implementation of aligned memory allocation

Thanks to evolution in CPU architecture, you have super computers in your house. However, to get benefit from it, it requires some techniques. There are something new, while there are something very traditional.
One of such traditional approach is to use aligned memory allocation. Because CPU access memory most efficiently when accessing in certain unit, it is better if the allocated memory lies in the certain unit boundary. For example, let’s assume a CPU architecture is most efficient when memory is aligned every 4 bytes. When it accesses memory located at multiples of 4 in its address space, it is much faster than when the accessed memory is at 0×03 or 0×05.
The Unix malloc functions usually return aligned memory space, while Windows version doesn’t. Instead, the Windows provide _aligned_malloc().
Then, how to create a aligned malloc() function? There can be some special cases that you want to implement your own aligned malloc, although I don’t imagine such a case. Let’s figure out how to by looking at one of existing implementations. ( You can search one using the Google, and you will find out that they are similar.)
01// size : the size of allocated memory
02//        The actual size of allocation will be greater than this size.
03// alignment : the alignment boundary
04void *aligned_memory_alloc( size_t size, size_t alignment )
05{
06    void *pa, *ptr;
07 
08    //pa=malloc(((size+alignment-1)&~(alignment-1))+sizeof(void *)+alignment-1);
09 
10    // 1
11    pa=malloc((size+alignment-1)+sizeof(void *));
12    if(!pa)
13        return NULL;
14 
15    // 2
16    ptr=(void*)( ((ULONG_PTR)pa+sizeof(void *)+alignment-1)&~(alignment-1) );
17 
18    // 3
19    *((void **)ptr-1)=pa;
20 
21    printf("CAlignedAlloc::new(%d,%d)=%x\n", (ULONG)size, alignment, (ULONG)ptr);
22 
23    return ptr;
24}

Point is to allocate more space than required and make it point to some position in the allocated memory. The pointed position is aligned location.
At 1, the total space to allocate is :
size ; the space a user want to allocate
+ (alignment-1) ; additional space due to the alignment
+ sizeof (void *) ; The head location of the newly allocated memory
; contains an address where the aligned memory block starts
The size part is obvious. The sizeof (void *) part follows the design of aligned memory allocation. Without this part, it will not know from where to free the aligned memory space, and from where to access the memory to read/write from/to the space.
For the (alignment-1), please take a look at this picture.

The red arrows show what the destination address should be if the allocated memory is 1, 2, 3 or 5, 6, 7. They are relocated to 4 and 8, respectively. So, it can be shifted up to 3 slots to the right. So, it is (alignment-1)
At 2, the ptr points to the location of aligned place. After reserving the space for storing where the whole allocated memory block is, i.e. pa, it calculates the aligned location. If you look at the picture above, you will see why (alignment-1) is added and the address is “AND”ed with 1′s complement of the (alignment-1). For example, 4-bytes alignment means masking out the last 2bits. It is like removing the last 2 bits.
At 3, “address length” bytes before, it saves the address which points where the whole allocated memory starts. Why it uses (void **) instead of (void *) is because the pointer (ptr-1) is points to an address, which is a pointer to pointer.

And finally it returns the aligned memory location, ptr.
How about the free() function? You can’t free the address to the aligned position. The whole memory space should be freed. That is why the starting address of the whole memory space was saved above.
1void aligned_free( void *ptr )
2{
3    printf("CAlignedAlloc::free(%x)\n", (ULONG)ptr);
4    if(ptr)
5        free(*((void **)ptr-1));
6}   

At Just 1 address-width, i.e. 4bytes for 32bit CPU and 8bytes for 64bit CPU, before the location of the aligned space, it contains the starting address of the whole block.
It is better to use (void **) or (void *) to calculate how much space is required to save a pointer, because it works for 64bit architecture as well as 32bit architecture. Actually it works for any architecture.

台灣網際網路連線頻寬圖

How to use simple speedtest in RaspberryPi CLI

  pi@ChunchaiRPI2:/tmp $  wget -O speedtest-cli https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py --2023-06-26 10:4...