summaryrefslogtreecommitdiffstats
path: root/src/trex_watchdog.h
blob: 0c1969b11402674138d6a95a53ab00b946a40f85 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
 Itay Marom
 Cisco Systems, Inc.
*/

/*
Copyright (c) 2015-2015 Cisco Systems, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#ifndef __TREX_WATCHDOG_H__
#define __TREX_WATCHDOG_H__

#include <string>
#include <vector>
#include <thread>
#include <mutex>

//#include "rte_memory.h"
#include "mbuf.h"
#include "os_time.h"

class TrexWatchDog {
public:
    TrexWatchDog() {
        m_thread  = NULL;
        m_active  = false;
        m_pending = 0;
        m_enable  = false;
    }

    void init(bool enable);

    /**
     * registering a monitor happens from another thread 
     * this make sure that start will be able to block until 
     * all threads has registered 
     * 
     * @author imarom (01-Jun-16)
     */
    void mark_pending_monitor(int count = 1);


    /**
     * blocks while monitors are pending registeration
     * 
     * @author imarom (01-Jun-16)
     */
    void block_on_pending(int max_block_time_ms = 200);


    /**
     * add a monitor to the watchdog 
     * this thread will be monitored and if timeout 
     * has passed without calling tick - an exception will be called
     * 
     * @author imarom (31-May-16)
     * 
     * @param name 
     * @param timeout 
     * 
     * @return int 
     */
    int register_monitor(const std::string &name, double timeout_sec);


    /**
     * disable a monitor - it will no longer be watched
     * 
     */
    void disable_monitor(int handle);


    /**
     * should be called by each thread on it's handle
     * 
     * @author imarom (31-May-16)
     * 
     * @param handle 
     */
    void tickle(int handle);


    /**
     * start the watchdog
     * 
     */
    void start();


    /**
     * stop the watchdog
     * 
     */
    void stop();


    /* should be cache aligned to avoid false sharing */
    struct monitor_st {
        /* write fields are first */
        volatile bool   active;
        volatile bool   tickled;
        dsec_t          ts;

        int             handle;
        double          timeout_sec;
        pthread_t       tid;
        std::string     name;

        /* for for a full cacheline */
        uint8_t       pad[15];
    } __rte_cache_aligned ;


private:
    void register_signal();
    void _main();


    std::vector<monitor_st> m_monitors __rte_cache_aligned;
    std::mutex              m_lock;
    bool                    m_enable;
    volatile bool           m_active;
    std::thread            *m_thread;
    volatile int            m_pending;

    static bool             g_signal_init;
};

static_assert(sizeof(TrexWatchDog::monitor_st) == RTE_CACHE_LINE_SIZE, "sizeof(monitor_st) != RTE_CACHE_LINE_SIZE" );

#endif /* __TREX_WATCHDOG_H__ */