docs: fix memory traces command
[vpp.git] / extras / gomemif / memif / packet_writer.go
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2020 Cisco and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *------------------------------------------------------------------
16  */
17
18 package memif
19
20 // WritePacket writes one packet to the shared memory and
21 // returns the number of bytes written
22 func (q *Queue) WritePacket(pkt []byte) int {
23         var mask int = q.ring.size - 1
24         var slot int
25         var nFree uint16
26         var packetBufferSize int = int(q.i.run.PacketBufferSize)
27
28         if q.i.args.IsMaster {
29                 slot = q.readTail()
30                 nFree = uint16(q.readHead() - slot)
31         } else {
32                 slot = q.readHead()
33                 nFree = uint16(q.ring.size - slot + q.readTail())
34         }
35
36         if nFree == 0 {
37                 q.interrupt()
38                 return 0
39         }
40
41         // copy descriptor from shm
42         desc := newDescBuf()
43         q.getDescBuf(slot&mask, desc)
44         // reset flags
45         desc.setFlags(0)
46         // reset length
47         if q.i.args.IsMaster {
48                 packetBufferSize = desc.getLength()
49         }
50         desc.setLength(0)
51         offset := desc.getOffset()
52
53         // write packet into memif buffer
54         n := copy(q.i.regions[desc.getRegion()].data[offset:offset+packetBufferSize], pkt[:])
55         desc.setLength(n)
56         for n < len(pkt) {
57                 nFree--
58                 if nFree == 0 {
59                         q.interrupt()
60                         return 0
61                 }
62                 desc.setFlags(descFlagNext)
63                 q.putDescBuf(slot&mask, desc)
64                 slot++
65
66                 // copy descriptor from shm
67                 q.getDescBuf(slot&mask, desc)
68                 // reset flags
69                 desc.setFlags(0)
70                 // reset length
71                 if q.i.args.IsMaster {
72                         packetBufferSize = desc.getLength()
73                 }
74                 desc.setLength(0)
75                 offset := desc.getOffset()
76
77                 tmp := copy(q.i.regions[desc.getRegion()].data[offset:offset+packetBufferSize], pkt[:])
78                 desc.setLength(tmp)
79                 n += tmp
80         }
81
82         // copy descriptor to shm
83         q.putDescBuf(slot&mask, desc)
84         slot++
85
86         if q.i.args.IsMaster {
87                 q.writeTail(slot)
88         } else {
89                 q.writeHead(slot)
90         }
91
92         q.interrupt()
93
94         return n
95 }