#include #include #include #include #include "sl.h" struct my_data { struct sl link; int data1; int data2; }; #define list_lock() do {} while (0) /* ToDo */ #define list_unlock() do {} while (0) /* ToDo */ struct my_data *new_dummy(void) { struct my_data *d = malloc(sizeof(*d)); memset(d, 0, sizeof(*d)); sl_init(&d->link); return d; } int link_dummy(struct my_data *d, struct sl *head) { sl_link(&d->link, head); return 0; } int unlink_dummy(struct my_data *d, struct sl *head) { struct sl *e, *prev = head; sl_for_each(e, head) { if (e != &d->link) { prev = e; continue; } sl_unlink(e, prev); return 1; /* for safety */ } return 0; } int print_dummy(struct my_data *data, void *arg) { char *msg = arg; printf("%sdata1: %d, data2: %d\n", msg ? msg : "", data->data1, data->data2); return 0; } struct my_data *search_dummy_by_data1(const int data1, const struct sl *head) { struct my_data *data; struct sl *e; sl_for_each(e, head) { data = sl_entry(e, struct my_data, link); if (data->data1 == data1) return data; } return NULL; } int remove_dummy_slow(const int data1, struct sl *head) { struct my_data *data; list_lock(); while ((data = search_dummy_by_data1(data1, head))) { unlink_dummy(data, head); list_unlock(); free(data); list_lock(); } list_unlock(); return 0; } int remove_dummy_fast(int data1, struct sl *head) { struct my_data *data; struct sl *e, *tmp, *prev = head; list_lock(); sl_for_each_safe(e, tmp, head) { data = sl_entry(e, struct my_data, link); if (data->data1 == data1) { sl_unlink(e, prev); free(data); } else prev = e; } list_unlock(); return 0; } int free_all_dummies(struct sl *head) { struct my_data *data; struct sl *e; list_lock(); while (!sl_empty(head)) { e = sl_next(head); sl_unlink(e, head); list_unlock(); data = sl_entry(e, struct my_data, link); print_dummy(data, "freeing "); free(data); list_lock(); } list_unlock(); return 0; } int for_all(const struct sl *head, int (cb)(struct my_data *, void *), void *arg) { struct my_data *data; struct sl *e; int r = 0; list_lock(); sl_for_each(e, head) { data = sl_entry(e, struct my_data, link); r = cb(data, arg); if (r < 0) break; }; list_unlock(); return r; } int __make_dummies(struct sl *head, int nr) { int i; for (i = 0; i < nr; i++) { struct my_data *d = new_dummy(); d->data1 = i / 2; d->data2 = (int)d; list_lock(); link_dummy(d, head); list_unlock(); } return 0; } int main(int argc, char **argv) { SL_DECLARE(head); __make_dummies(&head, 10); printf("dump_all\n"); for_all(&head, print_dummy, NULL); remove_dummy_slow(2, &head); printf("after_slow_removing '2's\n"); for_all(&head, print_dummy, NULL); remove_dummy_fast(3, &head); printf("after_fast_removing '3's\n"); for_all(&head, print_dummy, NULL); free_all_dummies(&head); printf("after_freeing\n"); for_all(&head, print_dummy, NULL); return 0; }