build: remove centos-7 directive from Makefile
[vpp.git] / extras / gomemif / memif / packet_reader.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 import "fmt"
21
22 // ReadPacket reads one packet form the shared memory and
23 // returns the number of bytes read
24 func (q *Queue) ReadPacket(pkt []byte) (int, error) {
25         var mask int = q.ring.size - 1
26         var slot int
27         var lastSlot int
28         var length int
29         var offset int
30         var pktOffset int = 0
31         var nSlots uint16
32         var desc descBuf = newDescBuf()
33
34         if q.i.args.IsMaster {
35                 slot = int(q.lastHead)
36                 lastSlot = q.readHead()
37         } else {
38                 slot = int(q.lastTail)
39                 lastSlot = q.readTail()
40         }
41
42         nSlots = uint16(lastSlot - slot)
43         if nSlots == 0 {
44                 goto refill
45         }
46
47         // copy descriptor from shm
48         q.getDescBuf(slot&mask, desc)
49         length = desc.getLength()
50         offset = desc.getOffset()
51
52         copy(pkt[:], q.i.regions[desc.getRegion()].data[offset:offset+length])
53         pktOffset += length
54
55         slot++
56         nSlots--
57
58         for (desc.getFlags() & descFlagNext) == descFlagNext {
59                 if nSlots == 0 {
60                         return 0, fmt.Errorf("Incomplete chained buffer, may suggest peer error.")
61                 }
62
63                 q.getDescBuf(slot&mask, desc)
64                 length = desc.getLength()
65                 offset = desc.getOffset()
66
67                 copy(pkt[pktOffset:], q.i.regions[desc.getRegion()].data[offset:offset+length])
68                 pktOffset += length
69
70                 slot++
71                 nSlots--
72         }
73
74 refill:
75         if q.i.args.IsMaster {
76                 q.lastHead = uint16(slot)
77                 q.writeTail(slot)
78         } else {
79                 q.lastTail = uint16(slot)
80
81                 head := q.readHead()
82
83                 for nSlots := uint16(q.ring.size - head + int(q.lastTail)); nSlots > 0; nSlots-- {
84                         q.setDescLength(head&mask, int(q.i.run.PacketBufferSize))
85                         head++
86                 }
87                 q.writeHead(head)
88         }
89
90         return pktOffset, nil
91 }