c 对象池

编译要求

需要 gcc, 版本 >= 4.7.2, 支持 __atomic* 内建同步函数

(理论上有 ABA 问题

lpool.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef _LPOOL_H_
#define _LPOOL_H_

struct lpool_node {
struct lpool_node *next;
};

struct lpool {
struct lpool_node *root;
struct lpool_node *(*alloc)();
void (*free)(struct lpool_node *n);
};

void lpool_clear(struct lpool *p);
struct lpool_node *lpool_get(struct lpool *p);
void lpool_put(struct lpool *p, struct lpool_node *n);

#endif /* !_LPOOL_H_ */

lpool.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include "lpool.h"
#include <stddef.h>

#define atomic_swap(p, v) __atomic_exchange_n((p), (v), __ATOMIC_ACQ_REL);
#define atomic_cas(p, pc, v) __atomic_compare_exchange_n((p), (pc), v, 1, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED)

void lpool_clear(struct lpool *p)
{
struct lpool_node *n;
struct lpool_node *t;

n = atomic_swap(&p->root, NULL);
while (n != NULL) {
t = n;
n = n->next;
p->free(t);
}
}

struct lpool_node *lpool_get(struct lpool *p)
{
struct lpool_node *n;

for (n = p->root; n != NULL; n = p->root) {
if (atomic_cas(&p->root, &n, n->next)) {
break;
}
}
if (n == NULL) {
n = p->alloc();
}
n->next = NULL;
return n;
}

void lpool_put(struct lpool *p, struct lpool_node *n)
{
do {
n->next = p->root;
} while (!atomic_cas(&p->root, &n->next, n));
}