static void slice_allocator_garbage_collect(slice_allocator_t *sa) { sa_hrtime_t now = osif_gethrtime(); int done = 0; lck_spin_lock(sa->spinlock); do { if (!list_is_empty(&sa->free)) { slice_t *slice = list_tail(&sa->free); #ifdef SA_CHECK_SLICE_SIZE if (sa != slice->sa) { REPORT0("slice_allocator_free - slice not owned by sa detected.\n") } #endif /* SA_CHECK_SLICE_SIZE */ if (now - slice->time_freed > SA_MAX_SLICE_FREE_MEM_AGE) { list_remove_tail(&sa->free); lck_spin_unlock(sa->spinlock); slice_fini(slice); osif_free(slice, sa->slice_size); lck_spin_lock(sa->spinlock); } else { done = 1; } } else { done = 1; } } while (!done);
txg_history_t * dsl_pool_txg_history_add(dsl_pool_t *dp, uint64_t txg) { txg_history_t *th, *rm; th = kmem_zalloc(sizeof(txg_history_t), KM_PUSHPAGE); mutex_init(&th->th_lock, NULL, MUTEX_DEFAULT, NULL); th->th_kstat.txg = txg; th->th_kstat.state = TXG_STATE_OPEN; th->th_kstat.birth = gethrtime(); mutex_enter(&dp->dp_lock); list_insert_head(&dp->dp_txg_history, th); dp->dp_txg_history_size++; while (dp->dp_txg_history_size > zfs_txg_history) { dp->dp_txg_history_size--; rm = list_remove_tail(&dp->dp_txg_history); mutex_destroy(&rm->th_lock); kmem_free(rm, sizeof(txg_history_t)); } mutex_exit(&dp->dp_lock); return (th); }
slice_allocator_alloc(slice_allocator_t *sa, sa_size_t size) #endif /* !DEBUG */ { slice_t *slice = 0; lck_spin_lock(sa->spinlock); /* * Locate a slice with residual capacity. First, check for a partially * full slice, and use some more of its capacity. Next, look to see if * we have a ready to go empty slice. If not, finally go to underlying * allocator for a new slice. */ if (!list_is_empty(&sa->partial)) { slice = list_head(&sa->partial); } else if (!list_is_empty(&sa->free)) { slice = list_tail(&sa->free); list_remove_tail(&sa->free); list_insert_head(&sa->partial, slice); } else { lck_spin_unlock(sa->spinlock); slice = (slice_t *)osif_malloc(sa->slice_size);; slice_init(slice, sa); lck_spin_lock(sa->spinlock); list_insert_head(&sa->partial, slice); } #ifdef SA_CHECK_SLICE_SIZE if (sa->max_alloc_size != slice->sa->max_alloc_size) { REPORT("slice_allocator_alloc - alloc size (%llu) sa %llu slice" " %llu\n", size, sa->max_alloc_size, slice->sa->max_alloc_size); } #endif /* SA_CHECK_SLICE_SIZE */ /* Grab memory from the slice */ #ifndef DEBUG void *p = slice_alloc(slice); #else void *p = slice_alloc(slice, size); #endif /* !DEBUG */ /* * Check to see if the slice buffer has become full. If it has, then * move it into the full list so that we no longer keep trying to * allocate from it. */ if (slice_is_full(slice)) { list_remove(&sa->partial, slice); #ifdef SLICE_ALLOCATOR_TRACK_FULL_SLABS list_insert_head(&sa->full, slice); #endif /* SLICE_ALLOCATOR_TRACK_FULL_SLABS */ } lck_spin_unlock(sa->spinlock); return (p); }
static int splat_list_test6(struct file *file, void *arg) { list_t list; list_item_t *li, *li_prev; int i, list_size = 8, rc = 0; splat_vprint(file, SPLAT_LIST_TEST6_NAME, "Creating list\n%s", ""); list_create(&list, sizeof(list_item_t), offsetof(list_item_t, li_node)); /* Insert all items at the list tail to form a queue */ splat_vprint(file, SPLAT_LIST_TEST6_NAME, "Adding %d items to list tail\n", list_size); for (i = 0; i < list_size; i++) { li = kmem_alloc(sizeof(list_item_t), KM_SLEEP); if (li == NULL) { rc = -ENOMEM; goto out; } list_link_init(&li->li_node); li->li_data = i; list_insert_tail(&list, li); } /* Remove all odd items from the queue */ splat_vprint(file, SPLAT_LIST_TEST6_NAME, "Removing %d odd items from the list\n", list_size >> 1); for (li = list_head(&list); li != NULL; li = list_next(&list, li)) { if (li->li_data % 2 == 1) { li_prev = list_prev(&list, li); list_remove(&list, li); kmem_free(li, sizeof(list_item_t)); li = li_prev; } } splat_vprint(file, SPLAT_LIST_TEST6_NAME, "Validating %d item " "list is a queue of only even elements\n", list_size / 2); rc = splat_list_validate(&list, list_size / 2, LIST_ORDER_QUEUE, 2); if (rc) splat_vprint(file, SPLAT_LIST_TEST6_NAME, "List validation failed, %d\n", rc); out: /* Remove all items */ splat_vprint(file, SPLAT_LIST_TEST6_NAME, "Removing %d items from list tail\n", list_size / 2); while ((li = list_remove_tail(&list))) kmem_free(li, sizeof(list_item_t)); splat_vprint(file, SPLAT_LIST_TEST6_NAME, "Destroying list\n%s", ""); list_destroy(&list); return rc; }
/** * Performs the finalization, i.e., calls all functions registered * with atcleanup(). */ void atcleanup_finalize(void) { struct atcleanup_node *node; if (!atcleanup_list_initialized) return; while ((node = (struct atcleanup_node*)list_remove_tail(&atcleanup_list))) { node->cleanup(node->user_data); free(node); } }
int main(int argc, char **argv) { struct person *p; int tmp_age; char tmp_name[32]; int i, n; list_t *l = list_init(); node_t *tmp_node; printf("Number of people: "); scanf("%d", &n); for (i = 0; i < n; ++i) { p = (struct person*)malloc(sizeof(struct person)); assert(p != NULL); printf("age: "); scanf("%d", &p->age); while(getchar()!='\n'); printf("name: "); fgets(p->name, 32, stdin); p->name[strlen(p->name) - 1] = '\0'; tmp_node = node_init(p); list_insert(l, tmp_node); } printf("List length: %d\n", l->length); printf("Traverse list forward\n"); list_traverse(l, LIST_FORWARD, dump_data); printf("Traverse list backward\n"); list_traverse(l, LIST_BACKWARD, dump_data); tmp_node = list_remove_head(l); printf("Removed node: \n"); dump_data(tmp_node); free(tmp_node); printf("New list. List length = %d\n", l->length); list_traverse(l, LIST_FORWARD, dump_data); tmp_node = list_remove_tail(l); printf("Removed node: \n"); dump_data(tmp_node); free(tmp_node); printf("New list. List length = %d\n", l->length); list_traverse(l, LIST_FORWARD, dump_data); list_free(l); return 0; }
err_t *err_get(void) { list_t *list = (list_t *) pthread_getspecific(__err_key); err_t *self = NULL; if (list != NULL) { self = container_of(list_remove_tail(list), err_t, node); if (list_empty(list)) { free(list), list = NULL; assert(pthread_setspecific(__err_key, list) == 0); } } return self; }
int main(void) { struct liste l; new_list(&l); add_first(1, &l); show_list(&l); printf( "#1\n" ); add_tail(2, &l); add_first(-10, &l); show_list(&l); printf( "#2\n" ); list_remove_tail(&l); show_list(&l); return 0; }
static int splat_list_test5(struct file *file, void *arg) { list_t list; list_item_t *li_new, *li_last = NULL; int i, list_size = 8, rc = 0; splat_vprint(file, SPLAT_LIST_TEST5_NAME, "Creating list\n%s", ""); list_create(&list, sizeof(list_item_t), offsetof(list_item_t, li_node)); /* Insert all items before the last item to form a stack */ splat_vprint(file, SPLAT_LIST_TEST5_NAME, "Adding %d items each before the last item\n", list_size); for (i = 0; i < list_size; i++) { li_new = kmem_alloc(sizeof(list_item_t), KM_SLEEP); if (li_new == NULL) { rc = -ENOMEM; goto out; } list_link_init(&li_new->li_node); li_new->li_data = i; list_insert_before(&list, li_last, li_new); li_last = li_new; } splat_vprint(file, SPLAT_LIST_TEST5_NAME, "Validating %d item list is a queue\n", list_size); rc = splat_list_validate(&list, list_size, LIST_ORDER_STACK, 1); if (rc) splat_vprint(file, SPLAT_LIST_TEST5_NAME, "List validation failed, %d\n", rc); out: /* Remove all items */ splat_vprint(file, SPLAT_LIST_TEST5_NAME, "Removing %d items from list tail\n", list_size); while ((li_new = list_remove_tail(&list))) kmem_free(li_new, sizeof(list_item_t)); splat_vprint(file, SPLAT_LIST_TEST5_NAME, "Destroying list\n%s", ""); list_destroy(&list); return rc; }
static void delete_messages(void) { struct error_node *node; set(error_wnd, MUIA_Window_Open, FALSE); while ((node = (struct error_node *)list_remove_tail(&error_list))) { if (node->text) free(node->text); free(node); } SetAttrs(error_numeric, MUIA_Numeric_Min, 0, MUIA_Numeric_Max, 0, MUIA_Numeric_Value, 0, MUIA_Numeric_Format, "Error 0/0", TAG_DONE); }
int main(int argc, char *argv[]) { off_t len, off = 0; int c, fd, options = 0, whence = SEEK_DATA; struct stat statbuf; char *fname; list_t seg_list; seg_t *seg = NULL; list_create(&seg_list, sizeof (seg_t), offsetof(seg_t, seg_node)); while ((c = getopt(argc, argv, "dhv")) != -1) { switch (c) { case 'd': options |= PRINT_DATA; break; case 'h': options |= PRINT_HOLE; break; case 'v': options |= PRINT_VERBOSE; break; } } argc -= optind; argv += optind; if (argc != 1) usage("Incorrect number of arguments.", 1); if ((fname = argv[0]) == NULL) usage("No filename provided.", 1); if ((fd = open(fname, O_LARGEFILE | O_RDONLY)) < 0) { perror("open failed"); exit(1); } if (fstat(fd, &statbuf) != 0) { perror("fstat failed"); exit(1); } len = statbuf.st_size; whence = starts_with_hole(fd); while ((off = lseek(fd, off, whence)) != -1) { seg_t *s; seg = umem_alloc(sizeof (seg_t), UMEM_DEFAULT); seg->seg_type = whence; seg->seg_offset = off; list_insert_tail(&seg_list, seg); if ((s = list_prev(&seg_list, seg)) != NULL) s->seg_len = seg->seg_offset - s->seg_offset; whence = whence == SEEK_HOLE ? SEEK_DATA : SEEK_HOLE; } if (errno != ENXIO) { perror("lseek failed"); exit(1); } (void) close(fd); /* * If this file ends with a hole block, then populate the length of * the last segment, otherwise this is the end of the file, so * discard the remaining zero length segment. */ if (seg && seg->seg_offset != len) { seg->seg_len = len - seg->seg_offset; } else { (void) list_remove_tail(&seg_list); } print_list(&seg_list, fname, options); list_destroy(&seg_list); return (0); }