summaryrefslogtreecommitdiffstats
path: root/src/stateless/cp/trex_dp_port_events.h
blob: be549a5517f517729f1b98e158a8310f636d59ed (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
/*
 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_DP_PORT_EVENTS_H__
#define __TREX_DP_PORT_EVENTS_H__

#include <unordered_map>
#include <string>

class TrexStatelessPort;
class TrexDpPortEvents;

/**
 * interface class for DP events
 * 
 * @author imarom (29-Feb-16)
 */
class TrexDpPortEvent {
    friend TrexDpPortEvents;

public:
    TrexDpPortEvent();
    virtual ~TrexDpPortEvent() {}

protected:
    /**
     * what to do when an event has been completed (all cores 
     * reported in 
     * 
     * @author imarom (29-Feb-16)
     */
    virtual void on_event() = 0;

    /**
     * when a thread ID encounter an error
     * 
     * @author imarom (20-Apr-16)
     * 
     * @param thread_id 
     */
    virtual void on_error(int thread_id) = 0;

    TrexStatelessPort *get_port() {
        return m_port;
    }

private:
    void init(TrexStatelessPort *port, int event_id, int timeout_ms);
    bool on_core_reporting_in(int thread_id, bool status = true);
    bool is_core_pending_on_event(int thread_id);

    std::unordered_map<int, bool>  m_signal;
    int                            m_pending_cnt;

    TrexStatelessPort             *m_port;
    int                            m_event_id;
    int                            m_expire_limit_ms;
};

/**
 * all the events related to a port
 * 
 */
class TrexDpPortEvents {
public:
    friend class TrexDpPortEvent;

    static const int INVALID_ID = -1;

    TrexDpPortEvents(TrexStatelessPort *port);

    /**
     * wait a new DP event on the port 
     * returns a key which will be used to identify 
     * the event happened 
     * 
     */
    int create_event(TrexDpPortEvent *event, int timeout_ms = -1);

    /**
     * destroy an event
     * 
     */
    void destroy_event(int event_id);

    /**
     * return when all DP cores have responsed on a barrier
     */
    void barrier();

    /**
     * a core has reached the event 
     */
    void on_core_reporting_in(int event_id, int thread_id, bool status = true);

    /**
     * return true if core has yet to respond 
     * to the event 
     * 
     */
    bool is_core_pending_on_event(int event_id, int thread_id);

private:
    TrexDpPortEvent *lookup(int event_id);

    static const int EVENT_ID_INVALID = -1;
    std::unordered_map<int, TrexDpPortEvent *> m_events;
    int m_event_id_counter;

    TrexStatelessPort *m_port;
    
};

#endif /* __TREX_DP_PORT_EVENTS_H__ */