- 论坛徽章:
- 11
|
本帖最后由 zylthinking 于 2013-08-18 23:43 编辑
zhouzhenghui 发表于 2013-08-18 23:20 ![]()
呵呵,我学乖测试过了,至少在这种场景是没问题的。错误在哪里也说不出来,注意这次队列的末指针是比较cur ...
你自己试试嘛
- #define _GNU_SOURCE
- #include <stdlib.h>
- #include <unistd.h>
- #include <stddef.h>
- #include <stdio.h>
- #include <assert.h>
- #include <pthread.h>
- #define rmb() __asm__ volatile("lfence":::"memory")
- #define wmb() __asm__ volatile("sfence":::"memory")
- struct lognode {
- struct lognode* next;
- };
- static struct lognode root = {0};
- static struct lognode* head = &root;
- static struct lognode* tail = &root;
- static struct lognode end;
- void lognode_put(struct lognode* node)
- {
- struct lognode* last;
- struct lognode* before ;
- do {
- last = tail;
- before = __sync_val_compare_and_swap(&(last->next), NULL, node);
- if (before != NULL)
- __sync_val_compare_and_swap(&tail, last, before);
- } while (before != NULL);
- __sync_val_compare_and_swap(&tail, last, node);
- }
- #if 1
- struct lognode* lognode_get()
- {
- if (head == tail) return head;
- struct lognode *node = head->next;
- if (!node) return head;
- head->next = NULL;
- lognode_put(head);
- return node;
- }
- #else
- struct lognode* lognode_get()
- {
- struct lognode *node = head->next;
- if (node == NULL) return &end;
- __sync_val_compare_and_swap(&tail, head, node);
- head->next = NULL;
- lognode_put(&end);
- __sync_val_compare_and_swap(&tail, &end, head);
- return node;
- }
- #endif
- #define nrp 10000
- #define nrt 1
- static volatile int run = 0;
- static struct lognode* pool = NULL;
- static volatile int indx = 0;
- void* writer(void* any)
- {
- while (run == 0) {
- usleep(100);
- }
- for (int i = 0; i < nrp; ++i) {
- int idx = __sync_fetch_and_add(&indx, 1);
- struct lognode* nodep = &pool[idx];
- nodep->next = NULL;
- lognode_put(nodep);
- }
- __sync_sub_and_fetch(&run, 1);
- return NULL;
- }
- int main(int argc, char** argv)
- {
- int n = 0;
- for (int i = 0; i < nrt; ++i) {
- pthread_t tid;
- if(0 == pthread_create(&tid, NULL, writer, NULL)) {
- ++n;
- pthread_detach(tid);
- }
- }
- int nr = nrp * n;
- pool = (struct lognode *) malloc(sizeof(struct lognode) * nr);
- if (pool == 0) {
- printf("memory\n");
- return 0;
- }
- run = n;
- printf("run = %d\n", run);
- printf("%d writer, nr = %d\n", n, nr);
- time_t t1 = time(0);
- while (run > 0) {
- struct lognode* nodep = lognode_get();
- struct lognode* cur = nodep;
- while (cur != &end) {
- nodep = nodep->next;
- cur = nodep;
- --nr;
- }
- time_t t2 = time(0);
- if (t2 > t1 + 3) {
- printf("%d %d\n", nr, indx);
- t1 = t2;
- }
- }
- struct lognode* nodep = lognode_get();
- struct lognode* cur = nodep;
- while (cur != &end) {
- nodep = nodep->next;
- cur = nodep;
- --nr;
- }
- printf("done %d\n", nr);
- return 0;
- }
复制代码 根据 #if 不同定义编译两次各自运行:
zylthinking@linux:~/code/test$ gcc a.c -lpthread -std=c99 -ggdb
zylthinking@linux:~/code/test$ ./a.out
run = 1
1 writer, nr = 10000
done 3981
zylthinking@linux:~/code/test$ gcc a.c -lpthread -std=c99 -ggdb
zylthinking@linux:~/code/test$ ./a.out
run = 1
1 writer, nr = 10000
Segmentation fault (core dumped)
|
|