Index: kernel/generic/src/adt/btree.c
===================================================================
--- kernel/generic/src/adt/btree.c	(revision ba2be23ed5b64c117eabda6070c8ad4ea3c56df6)
+++ kernel/generic/src/adt/btree.c	(revision f9f45e7ade54ca0d1a7465c54d5baeb53951c48b)
@@ -1031,9 +1031,5 @@
 	
 	printf("Printing list of leaves:\n");
-	list_foreach(t->leaf_list, cur) {
-		btree_node_t *node;
-		
-		node = list_get_instance(cur, btree_node_t, leaf_link);
-		
+	list_foreach(t->leaf_list, leaf_link, btree_node_t, node) {
 		ASSERT(node);
 		
Index: kernel/generic/src/adt/hash_table.c
===================================================================
--- kernel/generic/src/adt/hash_table.c	(revision ba2be23ed5b64c117eabda6070c8ad4ea3c56df6)
+++ kernel/generic/src/adt/hash_table.c	(revision f9f45e7ade54ca0d1a7465c54d5baeb53951c48b)
@@ -117,5 +117,6 @@
 	ASSERT(chain < h->entries);
 	
-	list_foreach(h->entry[chain], cur) {
+	link_t *cur = list_first(&h->entry[chain]);
+	while (cur != NULL) {
 		if (h->op->compare(key, h->max_keys, cur)) {
 			/*
@@ -124,4 +125,5 @@
 			return cur;
 		}
+		cur = list_next(cur, &h->entry[chain]);
 	}
 	
Index: kernel/generic/src/adt/list.c
===================================================================
--- kernel/generic/src/adt/list.c	(revision ba2be23ed5b64c117eabda6070c8ad4ea3c56df6)
+++ kernel/generic/src/adt/list.c	(revision f9f45e7ade54ca0d1a7465c54d5baeb53951c48b)
@@ -101,6 +101,8 @@
 	unsigned int count = 0;
 	
-	list_foreach(*list, link) {
+	link_t *link = list_first(list);
+	while (link != NULL) {
 		count++;
+		link = list_next(link, list);
 	}
 	
Index: kernel/generic/src/console/cmd.c
===================================================================
--- kernel/generic/src/console/cmd.c	(revision ba2be23ed5b64c117eabda6070c8ad4ea3c56df6)
+++ kernel/generic/src/console/cmd.c	(revision f9f45e7ade54ca0d1a7465c54d5baeb53951c48b)
@@ -656,8 +656,5 @@
 	
 	size_t len = 0;
-	list_foreach(cmd_list, cur) {
-		cmd_info_t *hlp;
-		hlp = list_get_instance(cur, cmd_info_t, link);
-		
+	list_foreach(cmd_list, link, cmd_info_t, hlp) {
 		spinlock_lock(&hlp->lock);
 		if (str_length(hlp->name) > len)
@@ -672,8 +669,5 @@
 	}
 	
-	list_foreach(cmd_list, cur) {
-		cmd_info_t *hlp;
-		hlp = list_get_instance(cur, cmd_info_t, link);
-		
+	list_foreach(cmd_list, link, cmd_info_t, hlp) {
 		spinlock_lock(&hlp->lock);
 		printf("%-*s %s\n", _len, hlp->name, hlp->description);
@@ -912,8 +906,5 @@
 	spinlock_lock(&cmd_lock);
 	
-	list_foreach(cmd_list, cur) {
-		cmd_info_t *hlp;
-		
-		hlp = list_get_instance(cur, cmd_info_t, link);
+	list_foreach(cmd_list, link, cmd_info_t, hlp) {
 		spinlock_lock(&hlp->lock);
 		
Index: kernel/generic/src/console/console.c
===================================================================
--- kernel/generic/src/console/console.c	(revision ba2be23ed5b64c117eabda6070c8ad4ea3c56df6)
+++ kernel/generic/src/console/console.c	(revision f9f45e7ade54ca0d1a7465c54d5baeb53951c48b)
@@ -125,6 +125,5 @@
 static void stdout_write(outdev_t *dev, wchar_t ch)
 {
-	list_foreach(dev->list, cur) {
-		outdev_t *sink = list_get_instance(cur, outdev_t, link);
+	list_foreach(dev->list, link, outdev_t, sink) {
 		if ((sink) && (sink->op->write))
 			sink->op->write(sink, ch);
@@ -134,6 +133,5 @@
 static void stdout_redraw(outdev_t *dev)
 {
-	list_foreach(dev->list, cur) {
-		outdev_t *sink = list_get_instance(cur, outdev_t, link);
+	list_foreach(dev->list, link, outdev_t, sink) {
 		if ((sink) && (sink->op->redraw))
 			sink->op->redraw(sink);
Index: kernel/generic/src/console/kconsole.c
===================================================================
--- kernel/generic/src/console/kconsole.c	(revision ba2be23ed5b64c117eabda6070c8ad4ea3c56df6)
+++ kernel/generic/src/console/kconsole.c	(revision f9f45e7ade54ca0d1a7465c54d5baeb53951c48b)
@@ -118,7 +118,5 @@
 	 * Make sure the command is not already listed.
 	 */
-	list_foreach(cmd_list, cur) {
-		cmd_info_t *hlp = list_get_instance(cur, cmd_info_t, link);
-		
+	list_foreach(cmd_list, link, cmd_info_t, hlp) {
 		if (hlp == cmd) {
 			/* The command is already there. */
@@ -612,6 +610,5 @@
 	cmd_info_t *cmd = NULL;
 	
-	list_foreach(cmd_list, cur) {
-		cmd_info_t *hlp = list_get_instance(cur, cmd_info_t, link);
+	list_foreach(cmd_list, link, cmd_info_t, hlp) {
 		spinlock_lock(&hlp->lock);
 		
Index: kernel/generic/src/ipc/ipc.c
===================================================================
--- kernel/generic/src/ipc/ipc.c	(revision ba2be23ed5b64c117eabda6070c8ad4ea3c56df6)
+++ kernel/generic/src/ipc/ipc.c	(revision f9f45e7ade54ca0d1a7465c54d5baeb53951c48b)
@@ -774,7 +774,5 @@
 static void ipc_print_call_list(list_t *list)
 {
-	list_foreach(*list, cur) {
-		call_t *call = list_get_instance(cur, call_t, ab_link);
-		
+	list_foreach(*list, ab_link, call_t, call) {
 #ifdef __32_BITS__
 		printf("%10p ", call);
Index: kernel/generic/src/ipc/ipcrsc.c
===================================================================
--- kernel/generic/src/ipc/ipcrsc.c	(revision ba2be23ed5b64c117eabda6070c8ad4ea3c56df6)
+++ kernel/generic/src/ipc/ipcrsc.c	(revision f9f45e7ade54ca0d1a7465c54d5baeb53951c48b)
@@ -151,6 +151,5 @@
 	irq_spinlock_lock(&TASK->answerbox.lock, true);
 	
-	list_foreach(TASK->answerbox.dispatched_calls, lst) {
-		call_t *call = list_get_instance(lst, call_t, ab_link);
+	list_foreach(TASK->answerbox.dispatched_calls, ab_link, call_t, call) {
 		if ((sysarg_t) call == callid) {
 			result = call;
Index: kernel/generic/src/lib/ra.c
===================================================================
--- kernel/generic/src/lib/ra.c	(revision ba2be23ed5b64c117eabda6070c8ad4ea3c56df6)
+++ kernel/generic/src/lib/ra.c	(revision f9f45e7ade54ca0d1a7465c54d5baeb53951c48b)
@@ -391,7 +391,5 @@
 
 	irq_spinlock_lock(&arena->lock, true);
-	list_foreach(arena->spans, cur) {
-		ra_span_t *span = list_get_instance(cur, ra_span_t, span_link);
-
+	list_foreach(arena->spans, span_link, ra_span_t, span) {
 		base = ra_span_alloc(span, size, alignment);
 		if (base)
@@ -407,7 +405,5 @@
 {
 	irq_spinlock_lock(&arena->lock, true);
-	list_foreach(arena->spans, cur) {
-		ra_span_t *span = list_get_instance(cur, ra_span_t, span_link);
-
+	list_foreach(arena->spans, span_link, ra_span_t, span) {
 		if (iswithin(span->base, span->size, base, size)) {
 			ra_span_free(span, base, size);
Index: kernel/generic/src/mm/as.c
===================================================================
--- kernel/generic/src/mm/as.c	(revision ba2be23ed5b64c117eabda6070c8ad4ea3c56df6)
+++ kernel/generic/src/mm/as.c	(revision f9f45e7ade54ca0d1a7465c54d5baeb53951c48b)
@@ -488,7 +488,5 @@
 	
 	/* Eventually check the addresses behind each area */
-	list_foreach(as->as_area_btree.leaf_list, cur) {
-		btree_node_t *node =
-		    list_get_instance(cur, btree_node_t, leaf_link);
+	list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t, node) {
 		
 		for (btree_key_t i = 0; i < node->keys; i++) {
@@ -904,7 +902,6 @@
 		 * reference from all frames found there.
 		 */
-		list_foreach(sh_info->pagemap.leaf_list, cur) {
-			btree_node_t *node
-			    = list_get_instance(cur, btree_node_t, leaf_link);
+		list_foreach(sh_info->pagemap.leaf_list, leaf_link,
+		    btree_node_t, node) {
 			btree_key_t i;
 			
@@ -956,9 +953,8 @@
 	 * Visit only the pages mapped by used_space B+tree.
 	 */
-	list_foreach(area->used_space.leaf_list, cur) {
-		btree_node_t *node;
+	list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
+	    node) {
 		btree_key_t i;
 		
-		node = list_get_instance(cur, btree_node_t, leaf_link);
 		for (i = 0; i < node->keys; i++) {
 			uintptr_t ptr = node->key[i];
@@ -1238,7 +1234,6 @@
 	size_t used_pages = 0;
 	
-	list_foreach(area->used_space.leaf_list, cur) {
-		btree_node_t *node
-		    = list_get_instance(cur, btree_node_t, leaf_link);
+	list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
+	    node) {
 		btree_key_t i;
 		
@@ -1264,7 +1259,6 @@
 	size_t frame_idx = 0;
 	
-	list_foreach(area->used_space.leaf_list, cur) {
-		btree_node_t *node = list_get_instance(cur, btree_node_t,
-		    leaf_link);
+	list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
+	    node) {
 		btree_key_t i;
 		
@@ -1316,7 +1310,6 @@
 	frame_idx = 0;
 	
-	list_foreach(area->used_space.leaf_list, cur) {
-		btree_node_t *node
-		    = list_get_instance(cur, btree_node_t, leaf_link);
+	list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
+	    node) {
 		btree_key_t i;
 		
@@ -2182,7 +2175,6 @@
 	size_t area_cnt = 0;
 	
-	list_foreach(as->as_area_btree.leaf_list, cur) {
-		btree_node_t *node =
-		    list_get_instance(cur, btree_node_t, leaf_link);
+	list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t,
+	    node) {
 		area_cnt += node->keys;
 	}
@@ -2195,7 +2187,6 @@
 	size_t area_idx = 0;
 	
-	list_foreach(as->as_area_btree.leaf_list, cur) {
-		btree_node_t *node =
-		    list_get_instance(cur, btree_node_t, leaf_link);
+	list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t,
+	    node) {
 		btree_key_t i;
 		
@@ -2231,7 +2222,6 @@
 	
 	/* Print out info about address space areas */
-	list_foreach(as->as_area_btree.leaf_list, cur) {
-		btree_node_t *node
-		    = list_get_instance(cur, btree_node_t, leaf_link);
+	list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t,
+	    node) {
 		btree_key_t i;
 		
Index: kernel/generic/src/mm/backend_anon.c
===================================================================
--- kernel/generic/src/mm/backend_anon.c	(revision ba2be23ed5b64c117eabda6070c8ad4ea3c56df6)
+++ kernel/generic/src/mm/backend_anon.c	(revision f9f45e7ade54ca0d1a7465c54d5baeb53951c48b)
@@ -118,9 +118,8 @@
 	 */
 	mutex_lock(&area->sh_info->lock);
-	list_foreach(area->used_space.leaf_list, cur) {
-		btree_node_t *node;
+	list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
+	    node) {
 		unsigned int i;
 		
-		node = list_get_instance(cur, btree_node_t, leaf_link);
 		for (i = 0; i < node->keys; i++) {
 			uintptr_t base = node->key[i];
Index: kernel/generic/src/mm/slab.c
===================================================================
--- kernel/generic/src/mm/slab.c	(revision ba2be23ed5b64c117eabda6070c8ad4ea3c56df6)
+++ kernel/generic/src/mm/slab.c	(revision f9f45e7ade54ca0d1a7465c54d5baeb53951c48b)
@@ -810,6 +810,5 @@
 	
 	size_t frames = 0;
-	list_foreach(slab_cache_list, cur) {
-		slab_cache_t *cache = list_get_instance(cur, slab_cache_t, link);
+	list_foreach(slab_cache_list, link, slab_cache_t, cache) {
 		frames += _slab_reclaim(cache, flags);
 	}
@@ -936,6 +935,5 @@
 	irq_spinlock_lock(&slab_cache_lock, false);
 	
-	list_foreach(slab_cache_list, cur) {
-		slab_cache_t *slab = list_get_instance(cur, slab_cache_t, link);
+	list_foreach(slab_cache_list, link, slab_cache_t, slab) {
 		if ((slab->flags & SLAB_CACHE_MAGDEFERRED) !=
 		    SLAB_CACHE_MAGDEFERRED)
Index: kernel/generic/src/proc/scheduler.c
===================================================================
--- kernel/generic/src/proc/scheduler.c	(revision ba2be23ed5b64c117eabda6070c8ad4ea3c56df6)
+++ kernel/generic/src/proc/scheduler.c	(revision f9f45e7ade54ca0d1a7465c54d5baeb53951c48b)
@@ -739,7 +739,6 @@
 			
 			printf("\trq[%u]: ", i);
-			list_foreach(cpus[cpu].rq[i].rq, cur) {
-				thread_t *thread = list_get_instance(cur,
-				    thread_t, rq_link);
+			list_foreach(cpus[cpu].rq[i].rq, rq_link, thread_t,
+			    thread) {
 				printf("%" PRIu64 "(%s) ", thread->tid,
 				    thread_states[thread->state]);
Index: kernel/generic/src/proc/task.c
===================================================================
--- kernel/generic/src/proc/task.c	(revision ba2be23ed5b64c117eabda6070c8ad4ea3c56df6)
+++ kernel/generic/src/proc/task.c	(revision f9f45e7ade54ca0d1a7465c54d5baeb53951c48b)
@@ -452,7 +452,5 @@
 	
 	/* Current values of threads */
-	list_foreach(task->threads, cur) {
-		thread_t *thread = list_get_instance(cur, thread_t, th_link);
-		
+	list_foreach(task->threads, th_link, thread_t, thread) {
 		irq_spinlock_lock(&thread->lock, false);
 		
@@ -484,6 +482,5 @@
 	 */
 	
-	list_foreach(task->threads, cur) {
-		thread_t *thread = list_get_instance(cur, thread_t, th_link);
+	list_foreach(task->threads, th_link, thread_t, thread) {
 		bool sleeping = false;
 		
Index: kernel/generic/src/synch/futex.c
===================================================================
--- kernel/generic/src/synch/futex.c	(revision ba2be23ed5b64c117eabda6070c8ad4ea3c56df6)
+++ kernel/generic/src/synch/futex.c	(revision f9f45e7ade54ca0d1a7465c54d5baeb53951c48b)
@@ -274,9 +274,7 @@
 	mutex_lock(&TASK->futexes_lock);
 
-	list_foreach(TASK->futexes.leaf_list, cur) {
-		btree_node_t *node;
+	list_foreach(TASK->futexes.leaf_list, leaf_link, btree_node_t, node) {
 		unsigned int i;
 		
-		node = list_get_instance(cur, btree_node_t, leaf_link);
 		for (i = 0; i < node->keys; i++) {
 			futex_t *ftx;
Index: kernel/generic/src/sysinfo/stats.c
===================================================================
--- kernel/generic/src/sysinfo/stats.c	(revision ba2be23ed5b64c117eabda6070c8ad4ea3c56df6)
+++ kernel/generic/src/sysinfo/stats.c	(revision f9f45e7ade54ca0d1a7465c54d5baeb53951c48b)
@@ -175,8 +175,6 @@
 	
 	/* Walk the B+ tree and count pages */
-	list_foreach(as->as_area_btree.leaf_list, cur) {
-		btree_node_t *node =
-		    list_get_instance(cur, btree_node_t, leaf_link);
-		
+	list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t,
+	    node) {
 		unsigned int i;
 		for (i = 0; i < node->keys; i++) {
@@ -218,8 +216,5 @@
 	
 	/* Walk the B+ tree and count pages */
-	list_foreach(as->as_area_btree.leaf_list, cur) {
-		btree_node_t *node =
-		    list_get_instance(cur, btree_node_t, leaf_link);
-		
+	list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t, node) {
 		unsigned int i;
 		for (i = 0; i < node->keys; i++) {
Index: kernel/generic/src/udebug/udebug.c
===================================================================
--- kernel/generic/src/udebug/udebug.c	(revision ba2be23ed5b64c117eabda6070c8ad4ea3c56df6)
+++ kernel/generic/src/udebug/udebug.c	(revision f9f45e7ade54ca0d1a7465c54d5baeb53951c48b)
@@ -406,7 +406,5 @@
 	
 	/* Finish debugging of all userspace threads */
-	list_foreach(task->threads, cur) {
-		thread_t *thread = list_get_instance(cur, thread_t, th_link);
-		
+	list_foreach(task->threads, th_link, thread_t, thread) {
 		mutex_lock(&thread->udebug.lock);
 		
Index: kernel/generic/src/udebug/udebug_ops.c
===================================================================
--- kernel/generic/src/udebug/udebug_ops.c	(revision ba2be23ed5b64c117eabda6070c8ad4ea3c56df6)
+++ kernel/generic/src/udebug/udebug_ops.c	(revision f9f45e7ade54ca0d1a7465c54d5baeb53951c48b)
@@ -196,7 +196,5 @@
 	/* Set udebug.active on all of the task's userspace threads. */
 	
-	list_foreach(TASK->threads, cur) {
-		thread_t *thread = list_get_instance(cur, thread_t, th_link);
-		
+	list_foreach(TASK->threads, th_link, thread_t, thread) {
 		mutex_lock(&thread->udebug.lock);
 		if (thread->uspace) {
@@ -389,7 +387,5 @@
 	
 	/* FIXME: make sure the thread isn't past debug shutdown... */
-	list_foreach(TASK->threads, cur) {
-		thread_t *thread = list_get_instance(cur, thread_t, th_link);
-		
+	list_foreach(TASK->threads, th_link, thread_t, thread) {
 		irq_spinlock_lock(&thread->lock, false);
 		bool uspace = thread->uspace;
