diff --git a/Makefile.dep b/Makefile.dep
index a9d163547b7a1217019b4e8bc3142a67e1d91cfd..94c2441f7e7a9f6ed724616c52106d9c917c7dee 100644
--- a/Makefile.dep
+++ b/Makefile.dep
@@ -2,6 +2,10 @@ ifneq (,$(filter gnrc_%,$(filter-out gnrc_netapi gnrc_netreg gnrc_netif% gnrc_pk
   USEMODULE += gnrc
 endif
 
+ifneq (,$(filter schedstatistics,$(USEMODULE)))
+  USEMODULE += xtimer
+endif
+
 ifneq (,$(filter gnrc_netif_default,$(USEMODULE)))
   USEMODULE += gnrc_netif
 endif
diff --git a/Makefile.pseudomodules b/Makefile.pseudomodules
index 1e123a297768035da59753f7a0d3af33c1f6d636..47b47a6699c370f96a589c836b772a005a1f1d56 100644
--- a/Makefile.pseudomodules
+++ b/Makefile.pseudomodules
@@ -13,6 +13,7 @@ PSEUDOMODULES += log
 PSEUDOMODULES += log_printfnoformat
 PSEUDOMODULES += newlib
 PSEUDOMODULES += pktqueue
+PSEUDOMODULES += schedstatistics
 
 # include variants of the AT86RF2xx drivers as pseudo modules
 PSEUDOMODULES += at86rf23%
diff --git a/core/hwtimer.c b/core/hwtimer.c
deleted file mode 100644
index b1bba3a2be29b8c72fa6c8cb07d312a80854e9c6..0000000000000000000000000000000000000000
--- a/core/hwtimer.c
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2014 Freie Universität Berlin
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License v2.1. See the file LICENSE in the top level
- * directory for more details.
- */
-
-/**
- * @ingroup     core_hwtimer
- * @{
- *
- * @file
- * @brief       Hardware timer abstraction implementation
- *
- * @author      Heiko Will <hwill@inf.fu-berlin.de>
- * @author      Thomas Hillebrandt <hillebra@inf.fu-berlin.de>
- * @author      Kaspar Schleiser <kaspar@schleiser.de>
- * @author      Oliver Hahm <oliver.hahm@fu-berlin.de>
- * @author      Kévin Roussel <Kevin.Roussel@inria.fr>
- *
- * @}
- */
-
-#include <stdio.h>
-
-#include "kernel.h"
-#include "thread.h"
-#include "lifo.h"
-#include "mutex.h"
-#include "irq.h"
-#include "board.h"
-
-#define ENABLE_DEBUG (0)
-#include "debug.h"
-
-#include "log.h"
-
-#include "hwtimer.h"
-#include "hwtimer_cpu.h"
-#include "arch/hwtimer_arch.h"
-
-/*---------------------------------------------------------------------------*/
-
-typedef struct hwtimer_t {
-    void (*callback)(void*);
-    void *data;
-} hwtimer_t;
-
-static hwtimer_t timer[HWTIMER_MAXTIMERS];
-static int lifo[HWTIMER_MAXTIMERS + 1];
-
-/*---------------------------------------------------------------------------*/
-
-static void multiplexer(int source)
-{
-    lifo_insert(lifo, source);
-    lpm_prevent_sleep--;
-
-    timer[source].callback(timer[source].data);
-}
-
-static void hwtimer_releasemutex(void* mutex) {
-    mutex_unlock((mutex_t*) mutex);
-}
-
-void hwtimer_spin(unsigned long ticks)
-{
-    DEBUG("hwtimer_spin ticks=%lu\n", ticks);
-
-    unsigned long start = hwtimer_arch_now();
-    /* compute destination time, possibly resulting in an overflow */
-    unsigned long stop = ((start + ticks) & HWTIMER_MAXTICKS);
-
-    /*
-     * If there is an overflow (that is: stop time is inferior to start),
-     * hwtimer_arch_now needs to spin until it has overflowed as well.
-     */
-    if (stop < start) {
-        while (hwtimer_arch_now() > start) /* do nothing */;
-    }
-
-    /* wait until we have passed destination (stop) time */
-    while (hwtimer_arch_now() < stop) /* do nothing again */;
-}
-
-/*---------------------------------------------------------------------------*/
-
-void hwtimer_init(void)
-{
-    hwtimer_init_comp(F_CPU);
-}
-
-/*---------------------------------------------------------------------------*/
-
-void hwtimer_init_comp(uint32_t fcpu)
-{
-    hwtimer_arch_init(multiplexer, fcpu);
-
-    lifo_init(lifo, HWTIMER_MAXTIMERS);
-
-    for (int i = 0; i < HWTIMER_MAXTIMERS; i++) {
-        lifo_insert(lifo, i);
-    }
-}
-
-/*---------------------------------------------------------------------------*/
-
-int hwtimer_active(void)
-{
-    return (!lifo_empty(lifo));
-}
-
-/*---------------------------------------------------------------------------*/
-
-unsigned long hwtimer_now(void)
-{
-    return hwtimer_arch_now();
-}
-
-/*---------------------------------------------------------------------------*/
-
-void hwtimer_wait(unsigned long ticks)
-{
-    DEBUG("hwtimer_wait ticks=%lu\n", ticks);
-
-    if ((ticks <= (HWTIMER_SPIN_BARRIER)) || inISR()) {
-        hwtimer_spin(ticks);
-        return;
-    }
-
-    mutex_t mutex = MUTEX_INIT;
-    mutex_lock(&mutex);
-    int res = hwtimer_set(ticks - (HWTIMER_WAIT_OVERHEAD), hwtimer_releasemutex, &mutex);
-    if (res == -1) {
-        mutex_unlock(&mutex);
-        hwtimer_spin(ticks);
-        return;
-    }
-
-    /* try to lock mutex again will cause the thread to go into
-     * STATUS_MUTEX_BLOCKED until hwtimer fires the releasemutex */
-    mutex_lock(&mutex);
-}
-
-/*---------------------------------------------------------------------------*/
-
-
-static int _hwtimer_set(unsigned long offset, void (*callback)(void*), void *ptr, bool absolute)
-{
-    DEBUG("_hwtimer_set: offset=%lu callback=%p ptr=%p absolute=%d\n", offset, callback, ptr, absolute);
-
-    unsigned state;
-
-    state = disableIRQ();
-
-    int n = lifo_get(lifo);
-
-    if (n == -1) {
-        restoreIRQ(state);
-
-        LOG_WARNING("No hwtimer left.\n");
-        return -1;
-    }
-
-    timer[n].callback = callback;
-    timer[n].data = ptr;
-
-    if (absolute) {
-        DEBUG("hwtimer_arch_set_absolute n=%d\n", n);
-        hwtimer_arch_set_absolute(offset, n);
-    }
-    else {
-        DEBUG("hwtimer_arch_set n=%d\n", n);
-        hwtimer_arch_set(offset, n);
-    }
-
-    lpm_prevent_sleep++;
-
-    restoreIRQ(state);
-
-    return n;
-}
-
-int hwtimer_set(unsigned long offset, void (*callback)(void*), void *ptr)
-{
-    return _hwtimer_set(offset, callback, ptr, false);
-}
-
-int hwtimer_set_absolute(unsigned long offset, void (*callback)(void*), void *ptr)
-{
-    return _hwtimer_set(offset, callback, ptr, true);
-}
-
-
-/*---------------------------------------------------------------------------*/
-
-int hwtimer_remove(int n)
-{
-    DEBUG("hwtimer_remove n=%d\n", n);
-
-    unsigned state = disableIRQ();
-    hwtimer_arch_unset(n);
-
-    lifo_insert(lifo, n);
-    timer[n].callback = NULL;
-
-    lpm_prevent_sleep--;
-
-    restoreIRQ(state);
-
-    return 1;
-}
diff --git a/core/include/arch/hwtimer_arch.h b/core/include/arch/hwtimer_arch.h
deleted file mode 100644
index 9a807235b44a4c9932a61d54d470b3e7ccdaadfe..0000000000000000000000000000000000000000
--- a/core/include/arch/hwtimer_arch.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2014 Freie Universität Berlin
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License v2.1. See the file LICENSE in the top level
- * directory for more details.
- */
-
-/**
- * @ingroup     core_arch
- * @{
- *
- * @file
- * @brief       The kernel's hardware timer abstraction interface
- *
- * @author      Thomas Hillebrandt <hillebra@inf.fu-berlin.de>
- * @author      Heiko Will <hwill@inf.fu-berlin.de>
- * @author      Kaspar Schleiser <kaspar@schleiser.de>
- * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
- */
-
-#ifndef HWTIMER_ARCH_H_
-#define HWTIMER_ARCH_H_
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-#include <stdint.h>
-
-/**
- * @brief Initialize architecture dependent kernel timer support
- *
- * @param[in] handler   callback that is called when timer @p offset is reached
- * @param[in] fcpu      the core CPU-frequency for tick interval calculation
- */
-void hwtimer_arch_init(void (*handler)(int), uint32_t fcpu);
-
-/**
- * @brief Enable interrupts of hardware timers
- */
-void hwtimer_arch_enable_interrupt(void);
-
-/**
- * @brief Disable interrupts of hardware timers
- */
-void hwtimer_arch_disable_interrupt(void);
-
-/**
- * @brief Set a kernel timer to raise an interrupt after @p offset kernel timer
- *              ticks from now
- *
- * @param[in] offset    number of ticks until the timer fires
- * @param[in] timer     the channel to set
- */
-void hwtimer_arch_set(unsigned long offset, short timer);
-
-/**
- * @brief Set a kernel timer to raise an interrupt at specified system time.
- *
- * @param[in] value     absolute timer tick value to set a timer channel to
- * @param[in] timer     the channel to set
- */
-void hwtimer_arch_set_absolute(unsigned long value, short timer);
-
-/**
- * @brief Unset the kernel timer with the given timer ID
- *
- * @param[in] timer     the channel to unset
- */
-void hwtimer_arch_unset(short timer);
-
-/**
- * @brief Get the current tick count of the default hardware timer
- *
- * @return              the current value of the hwtimer
- */
-unsigned long hwtimer_arch_now(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HWTIMER_ARCH_H_ */
-/** @} */
diff --git a/core/include/hwtimer.h b/core/include/hwtimer.h
deleted file mode 100644
index a32b39b164f540b563afeb3d1b89249c3eaa4502..0000000000000000000000000000000000000000
--- a/core/include/hwtimer.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2013 Freie Universität Berlin
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License v2.1. See the file LICENSE in the top level
- * directory for more details.
- */
-
-/**
- * @defgroup    core_hwtimer Hardware timer
- * @ingroup     core
- * @brief       Hardware timer interface
- *
- * The Hardware timers are directly mapped to hardware timers with minimum
- * latency. They are intended for short intervals and to be used in time
- * critical low-level drivers (e.g. radio). hwtimer callbacks are run in the
- * interrupt context and must use the shortest possible execution time (e.g.
- * set a flag and trigger a worker thread).
- *
- * <b>The hardware timer should not be used (until you know what
- * you're doing)</b>, use \ref sys_vtimer instead.
- *
- * @{
- *
- * @file
- * @brief       HW-timer abstraction
- *
- * @author      Heiko Will
- * @author      Kaspar Schleiser <kaspar@schleiser.de>
- * @author      Michael Baar
- */
-
-#ifndef HWTIMER_H
-#define HWTIMER_H
-
-#include <stdint.h>
-#include "hwtimer_cpu.h"
-#include "board.h"
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/**
- * @brief   Number of kernel timer ticks per second
- * @def     HWTIMER_SPEED
- */
-#ifndef HWTIMER_SPEED
-#warning "HWTIMER_SPEED undefined. Set HWTIMER_SPEED to the number of ticks \
-per second for the current architecture."
-#endif
-
-/**
- * @brief       Upper bound for hwtimer_spin
- *
- * @note        Barrier starting from which hwtimer_spin is called instead
- *              of setting a timer and yielding the thread.
- *
- *              Boards should override this.
- *
- * @def         HWTIMER_SPIN_BARRIER
- */
-#ifndef HWTIMER_SPIN_BARRIER
-#define HWTIMER_SPIN_BARRIER (6)
-#endif
-
-/**
- * @brief       Overhead of the `hwtimer_wait` function
- *
- * @note        This value is used to decrease the number of ticks that
- *              `hwtimer_wait` uses to set the actual hardware timer.
- *
- *              The goal is to make sure the number of ticks spent in the
- *              function corresponds to the ticks argument it was given.
- *
- *              Boards should override this.
- *
- * @def         HWTIMER_WAIT_OVERHEAD
- */
-#ifndef HWTIMER_WAIT_OVERHEAD
-#define HWTIMER_WAIT_OVERHEAD (2)
-#endif
-
-/**
- * @brief       Convert microseconds to kernel timer ticks
- * @param[in]   us number of microseconds
- * @return      kernel timer ticks
- */
-#if HWTIMER_SPEED > 1000000L
-#define HWTIMER_TICKS(us)        ((us) * (HWTIMER_SPEED / 1000000L))
-#else
-#define HWTIMER_TICKS(us)        ((us) / (1000000L / HWTIMER_SPEED))
-#endif
-
-/**
- * @brief       Convert ticks to microseconds
- * @param[in]   ticks   number of ticks
- * @return      microseconds
- */
-#if HWTIMER_SPEED > 1000000L
-#define HWTIMER_TICKS_TO_US(ticks)        ((ticks) / (HWTIMER_SPEED / 1000000L))
-#else
-#define HWTIMER_TICKS_TO_US(ticks)        ((ticks) * (1000000L / HWTIMER_SPEED))
-#endif
-
-/**
- * @brief   Maximum hwtimer tick count (before overflow)
- * @def     HWTIMER_MAXTICKS
- */
-#ifndef HWTIMER_MAXTICKS
-#warning "HWTIMER_MAXTICKS undefined. Set HWTIMER_MAXTICKS to the maximum \
-number of ticks countable on the current architecture."
-#endif
-
-/**
- * @brief   microseconds before hwtimer overflow
- */
-#if HWTIMER_SPEED > 1000000L
-#define HWTIMER_OVERFLOW_MICROS()        (HWTIMER_MAXTICKS / HWTIMER_SPEED * 1000000L)
-#else
-#define HWTIMER_OVERFLOW_MICROS()        (1000000L / HWTIMER_SPEED * HWTIMER_MAXTICKS)
-#endif
-
-typedef uint32_t timer_tick_t; /**< data type for hwtimer ticks */
-
-/**
- * @brief   initialize the hwtimer module
- */
-void hwtimer_init(void);
-
-/**
- * @brief   Get the hardware time
- * @return  The current tick count of the hardware timer
- */
-unsigned long hwtimer_now(void);
-
-/**
- * @brief Set a kernel timer
- * @param[in]   offset      Offset until callback invocation in timer ticks
- * @param[in]   callback    Callback function
- * @param[in]   ptr         Argument to callback function
- * @return      timer id
- */
-int hwtimer_set(unsigned long offset, void (*callback)(void*), void *ptr);
-
-/**
- * @brief Set a kernel timer
- * @param[in]   absolute    Absolute timer counter value for invocation
- *                          of handler
- * @param[in]   callback    Callback function
- * @param[in]   ptr         Argument to callback function
- * @return      timer id
- */
-int hwtimer_set_absolute(unsigned long absolute,
-        void (*callback)(void*), void *ptr);
-
-/**
- * @brief Remove a kernel timer
- * @param[in]   t   Id of timer to remove
- * @return      1 on success
- */
-int hwtimer_remove(int t);
-
-/**
- * @brief        Delay current thread
- * @param[in]    ticks  Number of kernel ticks to delay
- */
-void hwtimer_wait(unsigned long ticks);
-
-/**
- * @brief   determine if the hwtimer module is initialized
- * @return  1 if the hwtimer module is initialized
- */
-int hwtimer_active(void);
-
-/**
- * @brief       initialize hwtimer module data structures and hardware
- *
- * @param[in]   fcpu        cpu frequency
- */
-void hwtimer_init_comp(uint32_t fcpu);
-
-/**
- * @brief       Delay current thread, spinning. Use only in interrupts for
- *              VERY short delays!
- *
- * @param[in]   ticks        Number of kernel ticks to delay
- */
-void hwtimer_spin(unsigned long ticks);
-
-#ifdef __cplusplus
-}
-#endif
-
-/** @} */
-#endif /* HWTIMER_H */
diff --git a/core/include/sched.h b/core/include/sched.h
index 31ed0bb3b46b0a10dde903c248b8d3d500eb8c62..7f0436377afba5b45edb6a554532cedbcf94dca8 100644
--- a/core/include/sched.h
+++ b/core/include/sched.h
@@ -164,7 +164,7 @@ extern volatile kernel_pid_t sched_active_pid;
  */
 extern clist_node_t *sched_runqueues[SCHED_PRIO_LEVELS];
 
-#if SCHEDSTATISTICS
+#ifdef MODULE_SCHEDSTATISTICS
 /**
  *  Scheduler statistics
  */
diff --git a/core/kernel_init.c b/core/kernel_init.c
index 311c7a290a4958d683f8279b38279753b7c2ab8e..b89e1ad22dba7f0e1abad4d0d247d94a31098f08 100644
--- a/core/kernel_init.c
+++ b/core/kernel_init.c
@@ -29,10 +29,13 @@
 #include "cpu.h"
 #include "lpm.h"
 #include "thread.h"
-#include "hwtimer.h"
 #include "irq.h"
 #include "log.h"
 
+#ifdef MODULE_SCHEDSTATISTICS
+#include "sched.h"
+#endif
+
 #define ENABLE_DEBUG (0)
 #include "debug.h"
 
@@ -51,6 +54,11 @@ static void *main_trampoline(void *arg)
     auto_init();
 #endif
 
+#ifdef MODULE_SCHEDSTATISTICS
+    schedstat *stat = &sched_pidlist[thread_getpid()];
+    stat->laststart = 0;
+#endif
+
     LOG_INFO("main(): This is RIOT! (Version: " RIOT_VERSION ")\n");
 
     main();
@@ -85,8 +93,6 @@ void kernel_init(void)
 {
     (void) disableIRQ();
 
-    hwtimer_init();
-
     thread_create(idle_stack, sizeof(idle_stack),
             THREAD_PRIORITY_IDLE,
             CREATE_WOUT_YIELD | CREATE_STACKTEST,
diff --git a/core/sched.c b/core/sched.c
index a06c9cf41f617a6d22b40b922368a42e08bb0f04..2429496bdcfcef6f82286af1a992c0495fcb58f9 100644
--- a/core/sched.c
+++ b/core/sched.c
@@ -31,8 +31,8 @@
 #include "irq.h"
 #include "log.h"
 
-#if SCHEDSTATISTICS
-#include "hwtimer.h"
+#ifdef MODULE_SCHEDSTATISTICS
+#include "xtimer.h"
 #endif
 
 #define ENABLE_DEBUG (0)
@@ -55,7 +55,7 @@ volatile kernel_pid_t sched_active_pid = KERNEL_PID_UNDEF;
 clist_node_t *sched_runqueues[SCHED_PRIO_LEVELS];
 static uint32_t runqueue_bitcache = 0;
 
-#if SCHEDSTATISTICS
+#ifdef MODULE_SCHEDSTATISTICS
 static void (*sched_cb) (uint32_t timestamp, uint32_t value) = NULL;
 schedstat sched_pidlist[KERNEL_PID_LAST + 1];
 #endif
@@ -81,8 +81,8 @@ int sched_run(void)
         return 0;
     }
 
-#ifdef SCHEDSTATISTICS
-    unsigned long time = hwtimer_now();
+#ifdef MODULE_SCHEDSTATISTICS
+    unsigned long time = xtimer_now();
 #endif
 
     if (active_thread) {
@@ -96,7 +96,7 @@ int sched_run(void)
         }
 #endif
 
-#ifdef SCHEDSTATISTICS
+#ifdef MODULE_SCHEDSTATISTICS
         schedstat *active_stat = &sched_pidlist[active_thread->pid];
         if (active_stat->laststart) {
             active_stat->runtime_ticks += time - active_stat->laststart;
@@ -104,7 +104,7 @@ int sched_run(void)
 #endif
     }
 
-#if SCHEDSTATISTICS
+#ifdef MODULE_SCHEDSTATISTICS
     schedstat *next_stat = &sched_pidlist[next_thread->pid];
     next_stat->laststart = time;
     next_stat->schedules++;
@@ -122,7 +122,7 @@ int sched_run(void)
     return 1;
 }
 
-#if SCHEDSTATISTICS
+#ifdef MODULE_SCHEDSTATISTICS
 void sched_register_cb(void (*callback)(uint32_t, uint32_t))
 {
     sched_cb = callback;
diff --git a/core/thread.c b/core/thread.c
index 618c3d1f861e2757b03f86290dad882a4f1d30b5..5d4a5ed46952ec4a60f6ae05132316eb8ea8825d 100644
--- a/core/thread.c
+++ b/core/thread.c
@@ -29,7 +29,6 @@
 #include "debug.h"
 #include "kernel_internal.h"
 #include "bitarithm.h"
-#include "hwtimer.h"
 #include "sched.h"
 
 volatile tcb_t *thread_get(kernel_pid_t pid)