Exemple #1
0
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);
Exemple #2
0
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);
}
Exemple #3
0
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);
}
Exemple #4
0
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;
}
Exemple #5
0
/**
 * 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);
	}
}
Exemple #6
0
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;
}
Exemple #7
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;
}
Exemple #8
0
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;
}
Exemple #9
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;
}
Exemple #10
0
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);
}
Exemple #11
0
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);
}