void __bzero (void *s, size_t len);

/*

 將s的前len字節設為0

 思路:先對齊到4的倍數的地址上,對前面的幾B直接賦。然后,每次賦個32B,剩余湊不夠32B的,

 每次賦4B,剩余湊不夠4B的,直接賦

*/


void __bzero (void *s, size_t len)

{

    
long int dstp = (long int) s;

    
const op_t zero = 0;

 

    
if (len >= 8)

    
{

        size_t xlen;

        
// 處理前面的幾B,直到地址為4的倍數,然后可以每次4B

        
// 這樣做的原因與結構體對齊的原因一樣,是為提高讀寫數據的效率

        
// 由于len >= 8 ,OPSIZ=4,所以不必擔心len==0

        
while (dstp % OPSIZ != 0)   // #define op_t unsigned long int

                                    
// #define OPSIZ (sizeof(op_t))

                                    
// IA-32下是32

        
{

            ((
byte *) dstp)[0= 0;

            dstp 
+= 1;

            len 
-= 1;

        }


 

        
// 下面是典型的循環展開以提高效率,每次32B

        
// 若每次賦一個4B,程序會由于跳轉太多而打斷cpu流水線,降低效率

        
// http://www.lysator.liu.se/c/duffs-device.html

        
// 關鍵字:Duff's Device

        xlen 
= len / (OPSIZ * 8);

        
while (xlen != 0)

        
{

            ((op_t 
*) dstp)[0= zero;

            ((op_t 
*) dstp)[1= zero;

            ((op_t 
*) dstp)[2= zero;

            ((op_t 
*) dstp)[3= zero;

            ((op_t 
*) dstp)[4= zero;

            ((op_t 
*) dstp)[5= zero;

            ((op_t 
*) dstp)[6= zero;

            ((op_t 
*) dstp)[7= zero;

            dstp 
+= 8 * OPSIZ;

            xlen 
-= 1;

        }


        len 
%= OPSIZ * 8;           // 剩余的湊不足8 op_t 的

 

        xlen 
= len / OPSIZ;

        
while (xlen != 0)           // 每次填4B

        
{

            ((op_t 
*) dstp)[0= zero;

            dstp 
+= OPSIZ;

            xlen 
-= 1;

        }


        len 
%= OPSIZ;

    }


 

    
while (len != 0)                // 剩余不夠4B的,直接賦值

    
{

        ((
byte *) dstp)[0= 0;

        dstp 
+= 1;

        len 
-= 1;

    }


}