- 论坛徽章:
- 11
|
zhouzhenghui 发表于 2013-08-17 22:13 ![]()
正如starwing指出的那样,修改后的版本虽然put没有问题,但实际上存在活锁,就是必须等待另外一方做完事情才 ...
你确定你的代码测试过吗,- static struct lognode root = {0};
- static struct lognode* head = &root;
- static struct lognode* tail = &root;
- int nr_not_change_tail = 0;
- int up = 0, get = 0;
- void lognode_put(struct lognode* node)
- {
- struct lognode* before;
- struct lognode* last;
- 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);
- }
- struct lognode* lognode_get()
- {
- struct lognode temp = {0};
- tail = &temp;
- wmb();
- struct lognode* node = head->next;
- head->next = NULL;
- if (__sync_val_compare_and_swap(&tail, &temp, head) == &temp)
- if (temp.next) lognode_put(temp.next);
- else
- head->next = temp.next;
- return node;
- }
- #define nrp 1000000
- #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;
- }
- static int fetched[1024 * 1024 * 32];
- static int idx = 0;
- 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);
- int fch = 0;
- while (run > 0) {
- #if 1
- struct lognode* nodep = lognode_get();
- struct lognode* cur = nodep;
- while (cur != NULL) {
- //printf("%p feched\n", cur);
- nodep = nodep->next;
- cur = nodep;
- ++fch;
- --nr;
- }
- if (fch > 0) {
- fetched[idx++] = fch;
- fch = 0;
- }
- #endif
- 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 != NULL) {
- nodep = nodep->next;
- cur = nodep;
- ++fch;
- --nr;
- }
- if (fch > 0) {
- fetched[idx++] = fch;
- }
- printf("idx = %d\n", idx);
- printf("done %d, nr_not_change_tail = %d, up = %d, get %d\n", nr, nr_not_change_tail, up, get);
- return 0;
- n = 0;
- fch = 0;
- nr = 0;
- for (int i = 0; i < nrp; ++i) {
- ++fch;
- if (pool[i].next == NULL) {
- if(fch < fetched[n]) {
- assert(0);
- } else if (fch > fetched[n]) {
- if (nr < fch - fetched[n]) {
- nr = fch - fetched[n];
- }
- //printf("%d: %d, %d\n", n, fch, fetched[n]);
- }
- ++n;
- fch = 0;
- }
- }
- printf("%d get indeed, %d\n", n, nr);
- cur = &pool[0];
- for (int i = 1; i < nrp; ++i) {
- ++fch;
- if (cur->next != NULL) {
- assert(cur->next == &pool[i]);
- //printf("%d:%d\n", fetched[nr], fch);
- }
- cur = &pool[i];
- }
- printf("it's linked indeed\n");
- return 0;
- }
复制代码 运行结果:
run = 1
1 writer, nr = 1000000
idx = 238635
done 622448, nr_not_change_tail = 0, up = 0, get 0
凡是 done 不为 0 的, 一律存在 bug
|
|