1 : // Copyright 2012 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 : //
15 : // This file defines the trace::service::Buffer and BufferPool
16 : // structures, which are used to represent the shared memory buffers
17 : // used by the call_trace service.
18 :
19 : #ifndef SYZYGY_TRACE_SERVICE_BUFFER_POOL_H_
20 : #define SYZYGY_TRACE_SERVICE_BUFFER_POOL_H_
21 :
22 : #include <deque>
23 : #include <map>
24 : #include <utility>
25 : #include <vector>
26 :
27 : #include "base/basictypes.h"
28 : #include "base/win/scoped_handle.h"
29 : #include "syzygy/trace/rpc/call_trace_rpc.h"
30 :
31 : namespace trace {
32 : namespace service {
33 :
34 : // Forward declaration.
35 : class Session;
36 :
37 : // A Buffer extends the RPC defined CallTraceBuffer structure with the
38 : // extra bits needed by the internals of the Call Trace service.
39 : struct Buffer : public ::CallTraceBuffer {
40 : // A buffer is always in one of the following states.
41 : enum BufferState {
42 : kAvailable,
43 : kInUse,
44 : kPendingWrite,
45 : kBufferStateMax,
46 : };
47 :
48 : // Type used to identify a buffer. The first and second values in the
49 : // pair are the numeric id of the shared memory handle and the buffer
50 : // offset, respectively. See the GetID() method, below.
51 : typedef std::pair<unsigned long, unsigned long> ID;
52 :
53 : // Utility to get the ID for any buffer instance.
54 E : static ID GetID(const CallTraceBuffer& buffer) {
55 E : return std::make_pair(buffer.shared_memory_handle, buffer.buffer_offset);
56 E : }
57 :
58 : // We augment the buffer with some additional state.
59 : Session* session;
60 : uint8* data_ptr;
61 : BufferState state;
62 : };
63 :
64 : // A BufferPool manages a collection of buffers that all belong to the same
65 : // shared memory allocation.
66 : class BufferPool {
67 : public:
68 : BufferPool();
69 : ~BufferPool();
70 :
71 : // Allocates and maps a shared memory segment sufficiently large for
72 : // @p num_buffers, each of size @p buffer_size.
73 : bool Init(Session* session, size_t num_buffers, size_t buffer_size);
74 :
75 : // Updates each buffer in buffers_ with @p client_handle, which should be
76 : // a copy of handle_, valid in the client process these buffers are to be
77 : // shared with.
78 : // @p num_buffers, each of size @p buffer_size.
79 : void SetClientHandle(HANDLE client_handle);
80 :
81 E : Buffer* begin() { return &buffers_[0]; }
82 E : Buffer* end() { return begin() + buffers_.size(); }
83 :
84 : // Returns this pools shared memory segment handle.
85 E : HANDLE handle() const { return handle_.Get(); }
86 :
87 : private:
88 : typedef std::vector<Buffer> BufferCollection;
89 : // Sadly ScopedHandle is not const correct.
90 : mutable base::win::ScopedHandle handle_;
91 : uint8* base_ptr_;
92 : BufferCollection buffers_;
93 :
94 : DISALLOW_COPY_AND_ASSIGN(BufferPool);
95 : };
96 :
97 : } // namespace service
98 : } // namespace trace
99 :
100 : #endif // SYZYGY_TRACE_SERVICE_BUFFER_POOL_H_
|