TEMU  4.4
The Terma Emulator
Buffer.h
Go to the documentation of this file.
1 //===-- temu-c/Buffer.h - Data logger functions ------------*- C++ -*-===//
2 //
3 // TEMU: The Terma Emulator
4 // (c) Terma 2016
5 // Authors: Mattias Holm <maho (at) terma.com>
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef TEMU_SUPPORT_BUFFER_H
10 #define TEMU_SUPPORT_BUFFER_H
11 
12 #include <stdint.h>
13 #include <stdlib.h>
14 #include "temu-c/Support/Attributes.h"
15 
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19 
20 /*!
21  * Copy-On-Write (COW) buffer. The content is private and should not
22  * be manipulated directly.
23  *
24  * NOTE: The COW buffers are currently an EXPERIMENTAL feature. The
25  * API may change. Further, the temu_Buff type itself may change
26  * without notice in future versions of TEMU. The type is internal
27  * for the buffer API, but is exposed as a struct here to save on
28  * memory allocations when creating a temporary buffer object copy on
29  * the stack.
30  *
31  * The COW buffer objects are suitable for network simulation. Where a
32  * receiver may need to queue up multiple received packets.
33  *
34  * Currently, there is no way to prepend or append (e.g. injecting
35  * extra headers). However, it is possible to delete bytes from the
36  * head of the buffer without causing copies of the actual buffered
37  * data. This is enough to support efficient SpaceWire simulation.
38  *
39  * Typically a device model would use the buffers in this way:
40  *
41  * \code{.cpp}
42  * // Transaction start
43  * void
44  * startTransaction(mydevice_t *dev)
45  * {
46  * temu_Buff buffer = temu_buffCreate(dev->DataLengthRegister);
47  * uint8_t *bufferData = temu_buffWritableData(&buffer);
48  * dev->memspace.Iface->readBytes(dev->memspace.Obj,
49  * bufferData,
50  * dev->DataPtrRegister,
51  * dev->DataLengthRegister,
52  * 0); // Data in bytes
53  * sendData(dev->receiver, &buffer);
54  * temu_buffDispose(&buffer);
55  * }
56  *
57  * // RECEIVER functionality
58  * void
59  * receive(myreceiver_t *receiver, const temu_Buff *buff)
60  * {
61  * temu_Buff buffer = temu_buffCopy(buff);
62  * enqueue(receiver, buffer);
63  * temu_eventPostNs(receiver->Super.Queue, receiver->HandleDataEventID,
64  * 1000, teST_Cpu)
65  * }
66  *
67  * void
68  * event(temu_Event *ev)
69  * {
70  * myreceiver_t *receiver = ev->Obj;
71  * temu_Buff buffer = dequeue(receiver);
72  * const uint8_t *data temu_buffReadabledata(&buffer);
73  * uint32_t bufflen = temu_buffLen(&buffer);
74  * // ...
75  * temu_buffDispose(buffer);
76  * }
77  *
78  * \endcode
79  */
80 
81 #ifndef TEMU_BUFF_DEFINED
82 #define TEMU_BUFF_DEFINED
83 typedef struct {
84  uintptr_t data0;
85  uint32_t data1;
86  uint32_t data2;
87 } temu_Buff;
88 #endif // !TEMU_BUFF_DEFINED
89 
90 /*!
91  * Create a new COW buffer of size bytes.
92  *
93  * \param size Size of buffer in bytes
94  * \result Buffer object.
95  */
96 TEMU_API temu_Buff temu_buffCreate(uint32_t size);
97 
98 /*!
99  * Copy COW buffer. This will make a new buff object, but the
100  * underlying data will not be copied.
101  *
102  * \param B The buffer to copy.
103  * \result Buffer object referring to the same data as B.
104  */
105 TEMU_API temu_Buff temu_buffCopy(const temu_Buff *B);
106 
107 /*!
108  * Delete buffer. The buffer B will be deleted. If there are no more
109  * copies of the buffer data anywhere, the data will be deallocated.
110  *
111  * \param B buffer to delete.
112  */
114 
115 /*!
116  * Get a pointer to writable data.
117  *
118  * If the data have more than one reference, a new copy of the data
119  * will be created.
120  *
121  * \param B Buffer to get data pointer from.
122  * \result Pointer to writable data.
123  */
124 TEMU_API uint8_t* temu_buffWritableData(temu_Buff *B);
125 
126 /*!
127  * Get a pointer to readable buffer data
128  *
129  * The pointer to the readable data will be returned.
130  *
131  * \param B Buffer to get read pointer from
132  * \result Pointer to data buffer.
133  */
134 TEMU_API const uint8_t* temu_buffReadableData(const temu_Buff *B);
135 
136 /*!
137  * Get buffer length
138  *
139  * \param B buffer
140  * \result Length of buffer in bytes
141  */
142 TEMU_API uint32_t temu_buffLen(const temu_Buff *B);
143 
144 /*!
145  * Remove len bytes from the start of the buffer.
146  *
147  * Removing bytes from the buffer start will not change the underlying
148  * buffer object. And is not seen as a write for the purpose of the
149  * data block.
150  *
151  * This does not affect other copies of this buffer.
152  * \param B buffer to remove data from
153  * \param len Number of bytes to remove.
154  */
156 
157 /*!
158  * Remove len bytes from the end of the buffer.
159  *
160  * Removing bytes from the buffer tail will not change the underlying
161  * buffer object. And is not seen as a write for the purpose of the
162  * data block.
163  *
164  * This does not affect other copies of this buffer.
165  *
166  * \param B buffer to remove data from
167  * \param len Number of bytes to remove.
168  */
170 
171 #ifdef __cplusplus
172 }
173 #endif
174 
175 #endif /* ! TEMU_BUFFER_H */
temu_Buff::data0
uintptr_t data0
Definition: Buffer.h:84
temu_Buff::data1
uint32_t data1
Definition: Buffer.h:85
temu_buffDispose
TEMU_API void temu_buffDispose(temu_Buff *B)
temu_buffRemoveHead
TEMU_API void temu_buffRemoveHead(temu_Buff *B, uint32_t len)
temu_Buff::data2
uint32_t data2
Definition: Buffer.h:86
temu_buffRemoveTail
TEMU_API void temu_buffRemoveTail(temu_Buff *B, uint32_t len)