1/**
2 * \file
3 * \brief Microbenchmark to measure the cost of shared memory clock
4 */
5
6/*
7 * Copyright (c) 2007, 2008, 2009, ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#include <stdio.h>
16#include <barrelfish/barrelfish.h>
17#include <bench/bench.h>
18#include "clock.h"
19
20/*
21 * \brief compare and set. If the value at address
22 *        equals old, set it to new and return true,
23 *        otherwise don't write to address and return false
24 */
25static inline bool cas(volatile uintptr_t *address, uintptr_t old,
26        uintptr_t new)
27{
28    register bool res;
29    __asm volatile("lock; cmpxchgq %2,%0     \n\t"
30                   "setz %1                  \n\t"
31                   : "+m" (*address), "=q" (res)
32                   : "r" (new), "a" (old)
33                   : "memory");
34    return res;
35}
36
37static uintptr_t *pointer;
38
39timestamp_t clock_get_timestamp(void)
40{
41    while(1) {
42        uintptr_t time = *pointer;
43        if (cas(pointer, time, time + 1)) {
44            return time;
45        }
46    }
47}
48
49errval_t clock_init(struct capref cap)
50{
51    errval_t err;
52    void *buf;
53    err = vspace_map_one_frame(&buf, BASE_PAGE_SIZE, cap, NULL, NULL);
54    if (err_is_fail(err)) {
55        USER_PANIC_ERR(err, "clock_init failed");
56    }
57    pointer = (uintptr_t*)buf;
58
59    return SYS_ERR_OK;
60}
61