Statistics
| Branch: | Revision:

root / include / catomicopsdebug.h @ fbe00e73

History | View | Annotate | Download (2.97 KB)

1
//==========================================================================
2
//   CATOMICOPSDEBUG.H  -  header for
3
//                     Horizon/OMNeT++/OMNEST
4
//            Discrete System Simulation in C++
5
//
6
// Simple lock-based re-implementation of the atomic operations provided by
7
// libatomic-ops for debugging purposes.
8
//
9
//==========================================================================
10

    
11
/*--------------------------------------------------------------*
12
  Copyright (C) 2009 Georg Kunz
13

14
  This file is distributed WITHOUT ANY WARRANTY. See the file
15
  `license' for details on this and other legal matters.
16
*--------------------------------------------------------------*/
17

    
18
/*
19
 * This file provides a simple replacement for the libatomic-ops functions
20
 * used in Horizon. The implementation is based on s single global mutex lock
21
 * to emulate atomic behavior. This replacement is not intended to be used in
22
 * production code, but it merely used for debugging purposes in relation with
23
 * the Intel Thread Checker tool that does not correctly handle libatomic-ops.
24
 */
25
#ifndef __CATOMICOPSDEBUG_H
26
#define __CATOMICOPSDEBUG_H
27

    
28
#include <pthread.h>
29

    
30
//
31
// completely disable locking and atomic operations
32
//
33
#ifdef ATOMIC_OPS_DEBUG_PLAIN
34
    #define _lock(a)
35
    #define _unlock(a)
36
#else
37
    #define _lock(a) pthread_mutex_lock(a)
38
    #define _unlock(a) pthread_mutex_unlock(a)
39
#endif
40

    
41

    
42
//
43
// matching typedef to replace the original AO_t type
44
//
45
typedef size_t AO_t;
46

    
47
extern "C" pthread_mutex_t global_atomic_ops_debug_mutex;
48

    
49
inline AO_t AO_load(const volatile AO_t* addr)
50
{
51
        _lock(&global_atomic_ops_debug_mutex);
52
        AO_t tmp = *addr;
53
        _unlock(&global_atomic_ops_debug_mutex);
54
        return tmp;
55
}
56

    
57
inline AO_t AO_load_acquire(const volatile AO_t* addr)
58
{
59
        return AO_load(addr);
60
}
61

    
62
inline AO_t AO_load_read(const volatile AO_t* addr)
63
{
64
        return AO_load(addr);
65
}
66

    
67
inline AO_t AO_load_full(const volatile AO_t* addr)
68
{
69
    return AO_load(addr);
70
}
71

    
72
inline void AO_store(volatile AO_t* addr, AO_t value)
73
{
74
        _lock(&global_atomic_ops_debug_mutex);
75
        *addr = value;
76
        _unlock(&global_atomic_ops_debug_mutex);
77
}
78

    
79
inline void AO_store_write(volatile AO_t* addr, AO_t value)
80
{
81
        AO_store(addr, value);
82
}
83

    
84
inline void AO_store_full(volatile AO_t* addr, AO_t value)
85
{
86
    AO_store(addr, value);
87
}
88

    
89
inline void AO_store_release(volatile AO_t* addr, AO_t value)
90
{
91
        AO_store(addr, value);
92
}
93

    
94
inline AO_t AO_fetch_and_add1(volatile AO_t *addr)
95
{
96
        _lock(&global_atomic_ops_debug_mutex);
97
        AO_t tmp = *addr;
98
        (*addr)++;
99
        _unlock(&global_atomic_ops_debug_mutex);
100
        return tmp;
101
}
102

    
103
inline AO_t AO_fetch_and_sub1(volatile AO_t *addr)
104
{
105
        _lock(&global_atomic_ops_debug_mutex);
106
        AO_t tmp = *addr;
107
        (*addr)--;
108
        _unlock(&global_atomic_ops_debug_mutex);
109
        return tmp;
110
}
111

    
112
inline int AO_compare_and_swap_full(volatile AO_t *addr, AO_t old_val, AO_t new_val)
113
{
114
        AO_t ret = 0;
115
        _lock(&global_atomic_ops_debug_mutex);
116
        if (*addr == old_val)
117
        {
118
                *addr = new_val;
119
                ret = 1;
120
        }
121
        _unlock(&global_atomic_ops_debug_mutex);
122
        return ret;
123
}
124

    
125
#endif /* __CATOMICOPSDEBUG_H */