/*
* __kfifo_put - puts some data into the FIFO, no locking version
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these functions.
*/
unsigned int __kfifo_put(struct kfifo *fifo,
unsigned char *buffer, unsigned int len)
{
unsigned int l;
len = min(len, fifo->size - fifo->in + fifo->out);
/* first put the data starting from fifo->in to buffer end */
l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));
memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l);
/* then put the rest (if any) at the beginning of the buffer */
memcpy(fifo->buffer, buffer + l, len - l);
fifo->in += len;
return len;
}
/*
* __kfifo_get - gets some data from the FIFO, no locking version
* Note that with only one concurrent reader and one concurrent
* writer, you don't need extra locking to use these functions.
*/
unsigned int __kfifo_get(struct kfifo *fifo,
unsigned char *buffer, unsigned int len)
{
unsigned int l;
len = min(len, fifo->in - fifo->out);
/* first get the data from fifo->out until the end of the buffer */
l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));
memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), l);
/* then get the rest (if any) from the beginning of the buffer */
memcpy(buffer + l, fifo->buffer, len - l);
fifo->out += len;
return len;
}
以上代碼摘自 2.6.10 內核,通過代碼的注釋(斜體部分)可以看出,當只有一個消費者和一個生產者時,可以不用添加任何額外的鎖,就能達到對共享數(shù)據(jù)的訪問。 總結
通過對比 2.4 和 2.6 內核代碼,不得不佩服內核開發(fā)者的智慧,為了提高內核性能,一直不斷的進行各種優(yōu)化,并將業(yè)界最新的 lock-free 理念運用到內核中。
在實際開發(fā)過程中,進行無鎖設計時,首先進行場景分析,因為每種無鎖方案都有特定的應用場景,接著根據(jù)場景分析進行數(shù)據(jù)結構的初步設計,然后根據(jù)先前的分析結果進行并發(fā)模型建模,最后在調整數(shù)據(jù)結構的設計,以便達到最優(yōu)。
參考資料
Andrei Alexandrescu. 《 Lock-Free Data Structures--- Keeping threads moving while avoiding deadlock 》,《 Dr. Dobb's Journal 》, October 01, 2004。