list.c:
///
#include
#include
#include
#include
#include
//
// 链表节点
typedef struct node
{
struct node *next;
void *data_ptr;
}listnode;
// 链表头
typedef struct head
{
listnode *head;
listnode *end;
int size;
int state;
struct node first;
} listhead;
//
// 往链表里增加节点
static int list_add( listhead *list, void *data )
{
int ret = 0;
volatile listnode *last = 0;
volatile listnode *prev = 0;
listnode *node = (listnode*)malloc(sizeof(listnode));
if ( node == 0 )
{
return -1;
}
// last = list->end;
// list->end = node;
// last->data_ptr = data;
do
{
last = list->end;
#if 1
__asm__ __volatile__
(
// 该指令在cpu 486之后支持
"lock; cmpxchgl %k1, %2"
: "=a" (prev) // result, %0
: "r" (node), // new value
"m" (list->end), // old value
"0" (last) // %eax
: "memory"
);
#else
// gcc 4.1以后的版本支持
ret = __sync_bool_compare_and_swap(
&(list->end), last, node);
#endif
}while( prev != last );
last->next = node;
last->data_ptr = data;
// 表中节点数自增
__asm__ __volatile__( "lock; incl %0"
: "+m" (list->size) :: "memory" );
return 0;
}
// 取链表节点元素
static int list_next( listhead *list, void **pdata )
{
listnode *node = 0;
listnode *tmp = 0;
int ret = 0;
do
{
tmp = list->head;
if ( tmp->next == NULL )
{
return -1;
}
*pdata = tmp->data_ptr;
__asm__ __volatile__
(
"lock; cmpxchg %k1, %2; setz %0"
: "=m" (ret) // result, %0
: "r" (tmp->next), // new value
"m" (list->head), // old value
"a" (tmp) // %eax
: "memory"
);
} while( !ret );
// 表中节点数自减
__asm__ __volatile__( "lock; decl %0"
: "+m" (list->size) :: "memory" );
free( node );
return 0;
}
// 统计链表中所有节点数据
static int list_count( listhead *list )
{
int count = 0;
listnode *node = list->head;
FILE *fp = fopen( "list-nodes.txt", "w" );
while( node != 0 )
{
++count;
fprintf( fp, "node=%p\n", node );
node = node->next;
}
fprintf( fp, "list count is %d items, "
"list size is %d items.\n", count, list->size );
fprintf( stdout, "list count is %d items.\n", count );
fclose( fp );
return count;
}
// 对链表设置退出标志
static int list_exit( listhead *list )
{
list->state = 1; // 退出
return 0;
}
// 得到链表的退出状态
static int list_state( listhead *list )
{
return list->state;
}
// 获取链表的节点个数
static int list_size( listhead *list )
{
return list->size;
}
//
// 链表插入线程函数
static void *threadcb_add(void *arg)
{
listhead *list = (listhead*)arg;
int count = 100000;
int loop = 0;
for ( loop = 0; loop < count; loop++ )
{
list_add( list, &count );
}
printf( "%d插入了%d条数据\n",
(int)pthread_self(), count );
return 0;
}
// 链表取节点线程函数
static void *threadcb_next(void *arg)
{
listhead *list = (listhead*)arg;
int count = 0;
void *data = 0;
while ( 1 )
{
if ( list_state(list)
&& list_size(list) <= 0 )
{
break;
}
if ( list_next(list, &data) != 0 )
{
continue;
}
count++;
}
printf( "%d处理了%d条数据\n",
(int)pthread_self(), count );
return 0;
}
//
int main()
{
listhead list = {0};
pthread_t thread[4] = {0};
// 初始化
listnode *first = (listhead*)malloc( sizeof(listnode) );
memset( first, 0, sizeof(listnode) );
list.head = first;//&list.first;
list.end = first;//&list.first;
pthread_create( &(thread[0]), 0, threadcb_add, &list );
pthread_create( &(thread[1]), 0, threadcb_add, &list );
pthread_create( &(thread[2]), 0, threadcb_next, &list );
pthread_create( &(thread[3]), 0, threadcb_next, &list );
pthread_join( thread[0], 0 );
pthread_join( thread[1], 0 );
list_count( &list );
//pthread_create( &(thread[2]), 0, threadcb_next, &list );
//pthread_create( &(thread[3]), 0, threadcb_next, &list );
list_exit( &list );
pthread_join( thread[2], 0 );
pthread_join( thread[3], 0 );
return 0;
}
makefile:
all:
gcc -g -o list list.c -lpthread
.PHONY:run
run:
./list
.PHONY:gdb
gdb:
gdb ./list
.PHONY:clean
clean:
rm ./list