Index: kernel/generic/include/proc/task.h
===================================================================
--- kernel/generic/include/proc/task.h	(revision ef1eab71c59f1782c6211550d5ee608250a791e0)
+++ kernel/generic/include/proc/task.h	(revision d57c7c22ec10cecc3ee30ee28e44f7702e425a37)
@@ -158,4 +158,7 @@
 extern void task_release(task_t *);
 extern task_t *task_find_by_id(task_id_t);
+extern size_t task_count(void);
+extern task_t *task_first(void);
+extern task_t *task_next(task_t *);
 extern errno_t task_kill(task_id_t);
 extern void task_kill_self(bool) __attribute__((noreturn));
Index: kernel/generic/include/proc/thread.h
===================================================================
--- kernel/generic/include/proc/thread.h	(revision ef1eab71c59f1782c6211550d5ee608250a791e0)
+++ kernel/generic/include/proc/thread.h	(revision d57c7c22ec10cecc3ee30ee28e44f7702e425a37)
@@ -261,4 +261,7 @@
 extern void thread_destroy(thread_t *, bool);
 extern thread_t *thread_find_by_id(thread_id_t);
+extern size_t thread_count(void);
+extern thread_t *thread_first(void);
+extern thread_t *thread_next(thread_t *);
 extern void thread_update_accounting(bool);
 extern bool thread_exists(thread_t *);
Index: kernel/generic/src/proc/task.c
===================================================================
--- kernel/generic/src/proc/task.c	(revision ef1eab71c59f1782c6211550d5ee608250a791e0)
+++ kernel/generic/src/proc/task.c	(revision d57c7c22ec10cecc3ee30ee28e44f7702e425a37)
@@ -107,5 +107,4 @@
 {
 	size_t tasks_left;
-	odlink_t *odlink;
 	task_t *task;
 
@@ -128,8 +127,6 @@
 		tasks_left = 0;
 
-		odlink = odict_first(&tasks);
-		while (odlink != NULL) {
-			task = odict_get_instance(odlink, task_t, ltasks);
-
+		task = task_first();
+		while (task != NULL) {
 			if (task != TASK) {
 				tasks_left++;
@@ -140,5 +137,5 @@
 			}
 
-			odlink = odict_next(odlink, &tasks);
+			task = task_next(task);
 		}
 
@@ -452,4 +449,53 @@
 }
 
+/** Get count of tasks.
+ *
+ * @return Number of tasks in the system
+ */
+size_t task_count(void)
+{
+	assert(interrupts_disabled());
+	assert(irq_spinlock_locked(&tasks_lock));
+
+	return odict_count(&tasks);
+}
+
+/** Get first task (task with lowest ID).
+ *
+ * @return Pointer to first task or @c NULL if there are none.
+ */
+task_t *task_first(void)
+{
+	odlink_t *odlink;
+
+	assert(interrupts_disabled());
+	assert(irq_spinlock_locked(&tasks_lock));
+
+	odlink = odict_first(&tasks);
+	if (odlink == NULL)
+		return NULL;
+
+	return odict_get_instance(odlink, task_t, ltasks);
+}
+
+/** Get next task (with higher task ID).
+ *
+ * @param cur Current task
+ * @return Pointer to next task or @c NULL if there are no more tasks.
+ */
+task_t *task_next(task_t *cur)
+{
+	odlink_t *odlink;
+
+	assert(interrupts_disabled());
+	assert(irq_spinlock_locked(&tasks_lock));
+
+	odlink = odict_next(&cur->ltasks, &tasks);
+	if (odlink == NULL)
+		return NULL;
+
+	return odict_get_instance(odlink, task_t, ltasks);
+}
+
 /** Get accounting data of given task.
  *
@@ -658,12 +704,10 @@
 #endif
 
-	odlink_t *odlink;
 	task_t *task;
 
-	odlink = odict_first(&tasks);
-	while (odlink != NULL) {
-		task = odict_get_instance(odlink, task_t, ltasks);
+	task = task_first();
+	while (task != NULL) {
 		task_print(task, additional);
-		odlink = odict_next(odlink, &tasks);
+		task = task_next(task);
 	}
 
Index: kernel/generic/src/proc/thread.c
===================================================================
--- kernel/generic/src/proc/thread.c	(revision ef1eab71c59f1782c6211550d5ee608250a791e0)
+++ kernel/generic/src/proc/thread.c	(revision d57c7c22ec10cecc3ee30ee28e44f7702e425a37)
@@ -772,5 +772,4 @@
 void thread_print_list(bool additional)
 {
-	odlink_t *odlink;
 	thread_t *thread;
 
@@ -796,9 +795,8 @@
 #endif
 
-	odlink = odict_first(&threads);
-	while (odlink != NULL) {
-		thread = odict_get_instance(odlink, thread_t, lthreads);
+	thread = thread_first();
+	while (thread != NULL) {
 		thread_print(thread, additional);
-		odlink = odict_next(odlink, &threads);
+		thread = thread_next(thread);
 	}
 
@@ -860,5 +858,4 @@
 thread_t *thread_find_by_id(thread_id_t thread_id)
 {
-	odlink_t *odlink;
 	thread_t *thread;
 
@@ -866,14 +863,62 @@
 	assert(irq_spinlock_locked(&threads_lock));
 
-	odlink = odict_first(&threads);
-	while (odlink != NULL) {
-		thread = odict_get_instance(odlink, thread_t, lthreads);
+	thread = thread_first();
+	while (thread != NULL) {
 		if (thread->tid == thread_id)
 			return thread;
 
-		odlink = odict_next(odlink, &threads);
+		thread = thread_next(thread);
 	}
 
 	return NULL;
+}
+
+/** Get count of threads.
+ *
+ * @return Number of threads in the system
+ */
+size_t thread_count(void)
+{
+	assert(interrupts_disabled());
+	assert(irq_spinlock_locked(&threads_lock));
+
+	return odict_count(&threads);
+}
+
+/** Get first thread.
+ *
+ * @return Pointer to first thread or @c NULL if there are none.
+ */
+thread_t *thread_first(void)
+{
+	odlink_t *odlink;
+
+	assert(interrupts_disabled());
+	assert(irq_spinlock_locked(&threads_lock));
+
+	odlink = odict_first(&threads);
+	if (odlink == NULL)
+		return NULL;
+
+	return odict_get_instance(odlink, thread_t, lthreads);
+}
+
+/** Get next thread.
+ *
+ * @param cur Current thread
+ * @return Pointer to next thread or @c NULL if there are no more threads.
+ */
+thread_t *thread_next(thread_t *cur)
+{
+	odlink_t *odlink;
+
+	assert(interrupts_disabled());
+	assert(irq_spinlock_locked(&threads_lock));
+
+	odlink = odict_next(&cur->lthreads, &threads);
+	if (odlink == NULL)
+		return NULL;
+
+	return odict_get_instance(odlink, thread_t, lthreads);
 }
 
Index: kernel/generic/src/sysinfo/stats.c
===================================================================
--- kernel/generic/src/sysinfo/stats.c	(revision ef1eab71c59f1782c6211550d5ee608250a791e0)
+++ kernel/generic/src/sysinfo/stats.c	(revision d57c7c22ec10cecc3ee30ee28e44f7702e425a37)
@@ -246,5 +246,5 @@
 
 	/* Count the tasks */
-	size_t count = odict_count(&tasks);
+	size_t count = task_count();
 
 	if (count == 0) {
@@ -271,8 +271,6 @@
 	/* Gather the statistics for each task */
 	size_t i = 0;
-	odlink_t *odlink = odict_first(&tasks);
-	while (odlink != NULL) {
-		task_t *task = odict_get_instance(odlink, task_t, ltasks);
-
+	task_t *task = task_first();
+	while (task != NULL) {
 		/* Interrupts are already disabled */
 		irq_spinlock_lock(&(task->lock), false);
@@ -283,5 +281,5 @@
 
 		irq_spinlock_unlock(&(task->lock), false);
-		odlink = odict_next(odlink, &tasks);
+		task = task_next(task);
 	}
 
@@ -336,5 +334,5 @@
 
 	/* Count the threads */
-	size_t count = odict_count(&threads);
+	size_t count = thread_count();
 
 	if (count == 0) {
@@ -362,9 +360,6 @@
 	size_t i = 0;
 
-	odlink_t *odlink = odict_first(&threads);
-	while (odlink != NULL) {
-		thread_t *thread = odict_get_instance(odlink, thread_t,
-		    lthreads);
-
+	thread_t *thread = thread_first();
+	while (thread != NULL) {
 		/* Interrupts are already disabled */
 		irq_spinlock_lock(&thread->lock, false);
@@ -376,5 +371,5 @@
 		irq_spinlock_unlock(&thread->lock, false);
 
-		odlink = odict_next(odlink, &threads);
+		thread = thread_next(thread);
 	}
 
