亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
12下一頁
最近訪問板塊 發(fā)新帖
查看: 22445 | 回復(fù): 18
打印 上一主題 下一主題

內(nèi)核源碼kfifo分析(原創(chuàng)) [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2009-03-23 01:35 |只看該作者 |倒序瀏覽
從2.6.10開始,Linux內(nèi)核提供了一個通用的環(huán)形緩存(我喜歡稱為環(huán)形隊列);它的頭文件是<linux/kfifo.h>,kfifo.c是實現(xiàn)代碼。
在設(shè)備驅(qū)動中環(huán)形緩存出現(xiàn)相當(dāng)多. 網(wǎng)絡(luò)適配器, 特別地, 常常使用環(huán)形緩存來與處理器交換數(shù)據(jù)(報文)[LDD3]。

見下面的圖“LDD3中描述的隊列”。

我們來看下kfifo的數(shù)據(jù)結(jié)構(gòu):

struct kfifo {
&nbsp;&nbsp;&nbsp;&nbsp;unsigned char *buffer;&nbsp;&nbsp;&nbsp;&nbsp;/* the buffer holding the data */
&nbsp;&nbsp;&nbsp;&nbsp;unsigned int size;&nbsp;&nbsp;&nbsp;&nbsp;/* the size of the allocated buffer */
&nbsp;&nbsp;&nbsp;&nbsp;unsigned int in;&nbsp;&nbsp;&nbsp;&nbsp;/* data is added at offset (in % size) */
&nbsp;&nbsp;&nbsp;&nbsp;unsigned int out;&nbsp;&nbsp;&nbsp;&nbsp;/* data is extracted from off. (out % size) */
&nbsp;&nbsp;&nbsp;&nbsp;spinlock_t *lock;&nbsp;&nbsp;&nbsp;&nbsp;/* protects concurrent modifications */
};


如E文注釋所解,buffer指向隊列空間,對于隊列的操作,一般會涉及到讀寫,如果是多線程的話,就有可能涉及到生產(chǎn)者/消費者,也稱讀者/寫者問題;
size表示空間大小,必須為2^k,如果不是2^k大小,kfifo將會幫助用戶擴展到一個合適的大小;
in表示寫者指向的索引,在kfifo體統(tǒng)的put函數(shù)中,被處理為一個虛擬索引(我暫這么稱呼)。之所以稱之為虛擬索引,是因為該索引并不一定真正指向有效的地址空間,而是要通過一定運算才能得到真實的索引。下面的put/get代碼分析將會看到內(nèi)核是kfifo是怎么運算的。
out表示讀者指向的索引,out的更新與in一樣,都是使用了虛擬索引的概念,out總是小于等于in。

我們直接來看代碼(保留了原來的注釋,//后面的內(nèi)容為筆者的解釋)

/**
&nbsp;* kfifo_init - allocates a new FIFO using a preallocated buffer
&nbsp;* @buffer: the preallocated buffer to be used.
&nbsp;* @size: the size of the internal buffer, this have to be a power of 2.
&nbsp;* @gfp_mask: get_free_pages mask, passed to kmalloc()
&nbsp;* @lock: the lock to be used to protect the fifo buffer
&nbsp;*
&nbsp;* Do NOT pass the kfifo to kfifo_free() after use! Simply free the
&nbsp;* &struct kfifo with kfree().
&nbsp;*/

struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gfp_t gfp_mask, spinlock_t *lock)
{
&nbsp;&nbsp;&nbsp;&nbsp;struct kfifo *fifo;

&nbsp;&nbsp;&nbsp;&nbsp;/* size must be a power of 2 */
&nbsp;&nbsp;&nbsp;&nbsp;BUG_ON(size & (size - 1)); //大小必須為2的k次方(k>0)的目的在于put/get中從虛擬索引計算真實索引,size & (size - 1)是常用判斷技巧


&nbsp;&nbsp;&nbsp;&nbsp;fifo = kmalloc(sizeof(struct kfifo), gfp_mask); //分配kfifo數(shù)據(jù)結(jié)構(gòu)

&nbsp;&nbsp;&nbsp;&nbsp;if (!fifo)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return ERR_PTR(-ENOMEM);

&nbsp;&nbsp;&nbsp;&nbsp;fifo->buffer = buffer;
&nbsp;&nbsp;&nbsp;&nbsp;fifo->size = size;
&nbsp;&nbsp;&nbsp;&nbsp;fifo->in = fifo->out = 0; //當(dāng)fifo->in == fifo->out 時,表示空隊列

&nbsp;&nbsp;&nbsp;&nbsp;fifo->lock = lock;

&nbsp;&nbsp;&nbsp;&nbsp;return fifo;
}


/**
&nbsp;* kfifo_alloc - allocates a new FIFO and its internal buffer
&nbsp;* @size: the size of the internal buffer to be allocated.
&nbsp;* @gfp_mask: get_free_pages mask, passed to kmalloc()
&nbsp;* @lock: the lock to be used to protect the fifo buffer
&nbsp;*
&nbsp;* The size will be rounded-up to a power of 2.
&nbsp;*/

//通過調(diào)用kfifo_alloc分配隊列空間,該函數(shù)會調(diào)用kfifo_init初始化kfifo結(jié)構(gòu)體,并調(diào)整size的大小以適應(yīng)運算

struct kfifo *kfifo_alloc(unsigned int size, gfp_t gfp_mask, spinlock_t *lock)
{
&nbsp;&nbsp;&nbsp;&nbsp;unsigned char *buffer;
&nbsp;&nbsp;&nbsp;&nbsp;struct kfifo *ret;

&nbsp;&nbsp;&nbsp;&nbsp;/*
&nbsp;&nbsp;&nbsp;&nbsp; * round up to the next power of 2, since our 'let the indices
&nbsp;&nbsp;&nbsp;&nbsp; * wrap' tachnique works only in this case.
&nbsp;&nbsp;&nbsp;&nbsp; */

&nbsp;&nbsp;&nbsp;&nbsp;if (size & (size - 1)) { //如果size不是2的k次方,代碼將size調(diào)整最近的2^k次方附近

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BUG_ON(size > 0x80000000);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;size = roundup_pow_of_two(size);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;buffer = kmalloc(size, gfp_mask);
&nbsp;&nbsp;&nbsp;&nbsp;if (!buffer)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return ERR_PTR(-ENOMEM);

&nbsp;&nbsp;&nbsp;&nbsp;ret = kfifo_init(buffer, size, gfp_mask, lock);

&nbsp;&nbsp;&nbsp;&nbsp;if (IS_ERR(ret))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;kfree(buffer);

&nbsp;&nbsp;&nbsp;&nbsp;return ret;
}

/**
&nbsp;* __kfifo_put - puts some data into the FIFO, no locking version
&nbsp;* @fifo: the fifo to be used.
&nbsp;* @buffer: the data to be added.
&nbsp;* @len: the length of the data to be added.
&nbsp;*
&nbsp;* This function copies at most @len bytes from the @buffer into
&nbsp;* the FIFO depending on the free space, and returns the number of
&nbsp;* bytes copied.
&nbsp;*
&nbsp;* Note that with only one concurrent reader and one concurrent
&nbsp;* writer, you don't need extra locking to use these functions.
&nbsp;*/

unsigned int __kfifo_put(struct kfifo *fifo,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned char *buffer, unsigned int len)
{
&nbsp;&nbsp;&nbsp;&nbsp;unsigned int l;

&nbsp;&nbsp;&nbsp;&nbsp;//fifo->size - fifo->in + fifo->out,這段代碼計算空閑的空間

&nbsp;&nbsp;&nbsp;&nbsp;//in是寫索引,out是讀索引,而且put與get操作都是分別增加in與out的值來重新計算虛擬索引

&nbsp;&nbsp;&nbsp;&nbsp;//注意,out 始終不會大于 in,(in - out)是有效數(shù)據(jù)空間大小,size是總空間的大小

&nbsp;&nbsp;&nbsp;&nbsp;//那么空閑的空間大小就是 size - (int - out)

&nbsp;&nbsp;&nbsp;&nbsp;//如果請求的len大于空閑空間,就使len = size - (int - out)

&nbsp;&nbsp;&nbsp;&nbsp;len = min(len, fifo->size - fifo->in + fifo->out);

&nbsp;&nbsp;&nbsp;&nbsp;/*
&nbsp;&nbsp;&nbsp;&nbsp; * Ensure that we sample the fifo->out index -before- we
&nbsp;&nbsp;&nbsp;&nbsp; * start putting bytes into the kfifo.
&nbsp;&nbsp;&nbsp;&nbsp; */


&nbsp;&nbsp;&nbsp;&nbsp;smp_mb();

&nbsp;&nbsp;&nbsp;&nbsp;/* first put the data starting from fifo->in to buffer end */
&nbsp;&nbsp;&nbsp;&nbsp;//(fifo->in & (fifo->size - 1))這段代碼計算真實的寫索引偏移,筆者假設(shè)為real_in

&nbsp;&nbsp;&nbsp;&nbsp;//這是因為in在每次調(diào)用put之后都會增加一個len的長度

&nbsp;&nbsp;&nbsp;&nbsp;//由于fifo->size必定是2的k次方,而(fifo->size - 1)就是類似0x00FFFFF的值

&nbsp;&nbsp;&nbsp;&nbsp;//(fifo->in & (fifo->size - 1))的操作從數(shù)學(xué)角度將就是對長度fifo->size的取模運算

&nbsp;&nbsp;&nbsp;&nbsp;//這里能用AND運算代替取模運算得益于前面申請的空間大小為2^k次方

&nbsp;&nbsp;&nbsp;&nbsp;//l = min(空閑空間大小,從real_in開始到緩沖區(qū)結(jié)尾的空間)

&nbsp;&nbsp;&nbsp;&nbsp;l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));

&nbsp;&nbsp;&nbsp;&nbsp;//先從buffer中拷貝l字節(jié)到緩沖區(qū)剩余空間,l<=len,也<=從real_in開始到緩沖區(qū)結(jié)尾的空間

&nbsp;&nbsp;&nbsp;&nbsp;//所以這個copy可能沒拷貝完,但是不會造成緩沖區(qū)越界

&nbsp;&nbsp;&nbsp;&nbsp;memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l);

&nbsp;&nbsp;&nbsp;&nbsp;/* then put the rest (if any) at the beginning of the buffer */
&nbsp;&nbsp;&nbsp;&nbsp;//當(dāng)len > l時,拷貝buffer中剩余的內(nèi)容,其實地址當(dāng)然為buffer + l,而剩余的大小為len - l

&nbsp;&nbsp;&nbsp;&nbsp;//當(dāng)len == l時,下面的memcpy啥都不干,絕對精妙的算法

&nbsp;&nbsp;&nbsp;&nbsp;memcpy(fifo->buffer, buffer + l, len - l);

&nbsp;&nbsp;&nbsp;&nbsp;/*
&nbsp;&nbsp;&nbsp;&nbsp; * Ensure that we add the bytes to the kfifo -before-
&nbsp;&nbsp;&nbsp;&nbsp; * we update the fifo->in index.
&nbsp;&nbsp;&nbsp;&nbsp; */


&nbsp;&nbsp;&nbsp;&nbsp;smp_wmb();

&nbsp;&nbsp;&nbsp;&nbsp;//更新in(寫者)的邏輯索引

&nbsp;&nbsp;&nbsp;&nbsp;fifo->in += len;

&nbsp;&nbsp;&nbsp;&nbsp;return len;
}

/**
&nbsp;* __kfifo_get - gets some data from the FIFO, no locking version
&nbsp;* @fifo: the fifo to be used.
&nbsp;* @buffer: where the data must be copied.
&nbsp;* @len: the size of the destination buffer.
&nbsp;*
&nbsp;* This function copies at most @len bytes from the FIFO into the
&nbsp;* @buffer and returns the number of copied bytes.
&nbsp;*
&nbsp;* Note that with only one concurrent reader and one concurrent
&nbsp;* writer, you don't need extra locking to use these functions.
&nbsp;*/

unsigned int __kfifo_get(struct kfifo *fifo,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned char *buffer, unsigned int len)
{
&nbsp;&nbsp;&nbsp;&nbsp;unsigned int l;
&nbsp;&nbsp;&nbsp;&nbsp;//讀取的大小不能超過有效空間長度

&nbsp;&nbsp;&nbsp;&nbsp;//經(jīng)過min運算后len <= 請求的空間len, len <= size

&nbsp;&nbsp;&nbsp;&nbsp;len = min(len, fifo->in - fifo->out);

&nbsp;&nbsp;&nbsp;&nbsp;/*
&nbsp;&nbsp;&nbsp;&nbsp; * Ensure that we sample the fifo->in index -before- we
&nbsp;&nbsp;&nbsp;&nbsp; * start removing bytes from the kfifo.
&nbsp;&nbsp;&nbsp;&nbsp; */


&nbsp;&nbsp;&nbsp;&nbsp;smp_rmb();

&nbsp;&nbsp;&nbsp;&nbsp;/* first get the data from fifo->out until the end of the buffer */
&nbsp;&nbsp;&nbsp;&nbsp;//同理,fifo->out & (fifo->size - 1)等于out(讀者)的虛擬索引計算出來真實索引real_out

&nbsp;&nbsp;&nbsp;&nbsp;//fifo->size - real_out就等于該索引到緩沖區(qū)尾部的空間大小

&nbsp;&nbsp;&nbsp;&nbsp;//經(jīng)過min運算后,l<=len,l<=real_out至緩沖區(qū)尾部的空間大小

&nbsp;&nbsp;&nbsp;&nbsp;l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));

&nbsp;&nbsp;&nbsp;&nbsp;//從real_out開始拷貝l字節(jié)內(nèi)容到buffer中

&nbsp;&nbsp;&nbsp;&nbsp;memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), l);

&nbsp;&nbsp;&nbsp;&nbsp;/* then get the rest (if any) from the beginning of the buffer */
&nbsp;&nbsp;&nbsp;&nbsp;//如果l<len,那么從fifo->buffer的首部開始繼續(xù)拷貝剩下的內(nèi)容

&nbsp;&nbsp;&nbsp;&nbsp;//如果l == len,memcpy啥都不干

&nbsp;&nbsp;&nbsp;&nbsp;memcpy(buffer + l, fifo->buffer, len - l);

&nbsp;&nbsp;&nbsp;&nbsp;/*
&nbsp;&nbsp;&nbsp;&nbsp; * Ensure that we remove the bytes from the kfifo -before-
&nbsp;&nbsp;&nbsp;&nbsp; * we update the fifo->out index.
&nbsp;&nbsp;&nbsp;&nbsp; */


&nbsp;&nbsp;&nbsp;&nbsp;smp_mb();

&nbsp;&nbsp;&nbsp;&nbsp;//更新out(讀者)的虛擬索引

&nbsp;&nbsp;&nbsp;&nbsp;fifo->out += len;

&nbsp;&nbsp;&nbsp;&nbsp;return len;
}


      從上面幾個重要的函數(shù)可以看出一些特性,就是put函數(shù)能放入的數(shù)據(jù)長度永遠不會大于緩沖區(qū)的長度,而fifo->in - fifo->out永遠小于等于size。
get函數(shù)得到的數(shù)據(jù)永遠小于等于size(這個是必然的)。
在讀者/寫者問題中,發(fā)生互斥問題時,使用環(huán)形隊列是很好的解決方案。
fifo不太好的地方在于,想寫完整的話,必須保證空間足夠大,否則不能保證一次寫完,特別是在中斷調(diào)用過程中,如果阻塞了,然后讓讀者讀取內(nèi)容后騰出空間喚醒繼續(xù)寫,將會出現(xiàn)問題,唯一我能想到的方法就是申請大空間,以避免這種“沒寫完”的情況發(fā)生。不知道還有沒有其它方法,寫的不對的地方,大家討論討論,我是菜鳥,寫得也倉促,剛寫內(nèi)核代碼不久,請多指教。

[ 本帖最后由 springtty 于 2009-3-24 00:04 編輯 ]

ldd3-5-1.png (7.74 KB, 下載次數(shù): 189)

ldd3-5-1.png

_kfifo_.pdf

145.2 KB, 下載次數(shù): 850

評分

參與人數(shù) 2可用積分 +57 收起 理由
scutan + 30 原創(chuàng)內(nèi)容
prolj + 27 原創(chuàng)內(nèi)容

查看全部評分

論壇徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辭舊歲徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
2 [報告]
發(fā)表于 2009-03-23 12:30 |只看該作者
不錯,整個pdf就好了

論壇徽章:
36
IT運維版塊每日發(fā)帖之星
日期:2016-04-10 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-16 06:20:0015-16賽季CBA聯(lián)賽之廣東
日期:2016-04-16 19:59:32IT運維版塊每日發(fā)帖之星
日期:2016-04-18 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-19 06:20:00每日論壇發(fā)貼之星
日期:2016-04-19 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-25 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-06 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-08 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-13 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-28 06:20:00每日論壇發(fā)貼之星
日期:2016-05-28 06:20:00
3 [報告]
發(fā)表于 2009-03-23 13:13 |只看該作者
分析的比較詳細。

論壇徽章:
36
IT運維版塊每日發(fā)帖之星
日期:2016-04-10 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-16 06:20:0015-16賽季CBA聯(lián)賽之廣東
日期:2016-04-16 19:59:32IT運維版塊每日發(fā)帖之星
日期:2016-04-18 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-19 06:20:00每日論壇發(fā)貼之星
日期:2016-04-19 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-25 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-06 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-08 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-13 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-28 06:20:00每日論壇發(fā)貼之星
日期:2016-05-28 06:20:00
4 [報告]
發(fā)表于 2009-03-23 13:20 |只看該作者
考慮到一個極限的情況啊。因為這里的in和out是一直增加的,那么當(dāng)存在in溢出,out還沒溢出的時候,是不是有一定的問題了?
    //注意,out 始終不會大于 in,(in - out)是有效數(shù)據(jù)空間大小,size是總空間的大小

    //那么空閑的空間大小就是 size - (int - out)

    //如果請求的len大于空閑空間,就使len = size - (int - out)

    len = min(len, fifo->size - fifo->in + fifo->out);

[ 本帖最后由 Godbach 于 2009-3-23 13:27 編輯 ]

論壇徽章:
0
5 [報告]
發(fā)表于 2009-03-23 23:51 |只看該作者
原帖由 Godbach 于 2009-3-23 13:20 發(fā)表
考慮到一個極限的情況啊。因為這里的in和out是一直增加的,那么當(dāng)存在in溢出,out還沒溢出的時候,是不是有一定的問題了?

是的,就是考慮到這種情況。
謝謝各位老大的鼓勵:)

論壇徽章:
36
IT運維版塊每日發(fā)帖之星
日期:2016-04-10 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-16 06:20:0015-16賽季CBA聯(lián)賽之廣東
日期:2016-04-16 19:59:32IT運維版塊每日發(fā)帖之星
日期:2016-04-18 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-19 06:20:00每日論壇發(fā)貼之星
日期:2016-04-19 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-25 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-06 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-08 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-13 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-28 06:20:00每日論壇發(fā)貼之星
日期:2016-05-28 06:20:00
6 [報告]
發(fā)表于 2009-03-24 09:56 |只看該作者
原帖由 springtty 于 2009-3-23 23:51 發(fā)表

是的,就是考慮到這種情況。
謝謝各位老大的鼓勵:)


出現(xiàn)in溢出的時候:
    //如果請求的len大于空閑空間,就使len = size - (int - out)

    len = min(len, fifo->size - fifo->in + fifo->out);

這個結(jié)果還正確嗎?

論壇徽章:
0
7 [報告]
發(fā)表于 2009-03-25 12:56 |只看該作者
原帖由 Godbach 于 2009-3-24 09:56 發(fā)表


出現(xiàn)in溢出的時候:

這個結(jié)果還正確嗎?

這里的in溢出而out沒有溢出是不是指 in(寫入)而out(讀。┑闹羔槶h(huán)繞的情況。
這里應(yīng)該避免這種情況,要不然就不能達到互斥訪問緩沖區(qū)的目的了。

[ 本帖最后由 springtty 于 2009-3-25 13:01 編輯 ]

論壇徽章:
36
IT運維版塊每日發(fā)帖之星
日期:2016-04-10 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-16 06:20:0015-16賽季CBA聯(lián)賽之廣東
日期:2016-04-16 19:59:32IT運維版塊每日發(fā)帖之星
日期:2016-04-18 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-19 06:20:00每日論壇發(fā)貼之星
日期:2016-04-19 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-25 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-06 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-08 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-13 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-28 06:20:00每日論壇發(fā)貼之星
日期:2016-05-28 06:20:00
8 [報告]
發(fā)表于 2009-03-25 14:06 |只看該作者
原帖由 springtty 于 2009-3-25 12:56 發(fā)表

這里的in溢出而out沒有溢出是不是指 in(寫入)而out(讀。┑闹羔槶h(huán)繞的情況。
這里應(yīng)該避免這種情況,要不然就不能達到互斥訪問緩沖區(qū)的目的了。


這里的in和out不都是unsigned int類型的嘛。而且你說out 不會大于in的。

那么當(dāng)出現(xiàn)in超過該類型的最大值時,是不是溢出了,它的值是不是回繞到比較小的無符號整數(shù)了。

論壇徽章:
0
9 [報告]
發(fā)表于 2009-03-25 22:52 |只看該作者
原帖由 Godbach 于 2009-3-25 14:06 發(fā)表


這里的in和out不都是unsigned int類型的嘛。而且你說out 不會大于in的。

那么當(dāng)出現(xiàn)in超過該類型的最大值時,是不是溢出了,它的值是不是回繞到比較小的無符號整數(shù)了。

我理解錯了,以為是buffer的溢出。
你說的情況確實存在,我只考慮數(shù)學(xué)層面上的東西了。
不過如果真的發(fā)生這種情況,程序還是正確的:
        unsigned int out        = 0xfffffff0;
        unsigned int in        = 0x00000006;
       
        printf("%u\n", in - out);
gcc打印出來的值等于22。

0x00000006
-0xfffffff0
================

0x00000016 = 22

論壇徽章:
36
IT運維版塊每日發(fā)帖之星
日期:2016-04-10 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-16 06:20:0015-16賽季CBA聯(lián)賽之廣東
日期:2016-04-16 19:59:32IT運維版塊每日發(fā)帖之星
日期:2016-04-18 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-19 06:20:00每日論壇發(fā)貼之星
日期:2016-04-19 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-04-25 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-06 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-08 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-13 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-05-28 06:20:00每日論壇發(fā)貼之星
日期:2016-05-28 06:20:00
10 [報告]
發(fā)表于 2009-03-25 23:10 |只看該作者
原帖由 springtty 于 2009-3-25 22:52 發(fā)表

我理解錯了,以為是buffer的溢出。
你說的情況確實存在,我只考慮數(shù)學(xué)層面上的東西了。
不過如果真的發(fā)生這種情況,程序還是正確的:
        unsigned int out        = 0xfffffff0;
        unsigned int in        = 0x00000006;
...


buffer的話應(yīng)該不會溢出了,程序里面已經(jīng)控制好了。
在接著寫的時候,實際可寫的長度通過如下代碼判斷,就算in是溢出的值,應(yīng)該也沒有問題。
len = min(len, fifo->size - fifo->in + fifo->out);

[ 本帖最后由 Godbach 于 2009-3-25 23:27 編輯 ]
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP