mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
GB28181: Support GB28181-2016 protocol. v5.0.74 (#3201)
01. Support GB config as StreamCaster. 02. Support disable GB by --gb28181=off. 03. Add utests for SIP examples. 04. Wireshark plugin to decode TCP/9000 as rtp.rfc4571 05. Support MPEGPS program stream codec. 06. Add utest for PS stream codec. 07. Decode MPEGPS packet stream. 08. Carry RTP and PS packet as helper in PS message. 09. Support recover from error mode. 10. Support process by a pack of PS/TS messages. 11. Add statistic for recovered and msgs dropped. 12. Recover from err position fastly. 13. Define state machine for GB session. 14. Bind context to GB session. 15. Re-invite when media disconnected. 16. Update GitHub actions with GB28181. 17. Support parse CANDIDATE by env or pip. 18. Support mux GB28181 to RTMP. 19. Support regression test by srs-bench.
This commit is contained in:
parent
9c81a0e1bd
commit
5a420ece3b
298 changed files with 43343 additions and 763 deletions
21
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/LICENSE
generated
vendored
Normal file
21
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017-2019 Sergey Kamardin <gobwas@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
107
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/README.md
generated
vendored
Normal file
107
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/README.md
generated
vendored
Normal file
|
@ -0,0 +1,107 @@
|
|||
# pool
|
||||
|
||||
[![GoDoc][godoc-image]][godoc-url]
|
||||
|
||||
> Tiny memory reuse helpers for Go.
|
||||
|
||||
## generic
|
||||
|
||||
Without use of subpackages, `pool` allows to reuse any struct distinguishable
|
||||
by size in generic way:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "github.com/gobwas/pool"
|
||||
|
||||
func main() {
|
||||
x, n := pool.Get(100) // Returns object with size 128 or nil.
|
||||
if x == nil {
|
||||
// Create x somehow with knowledge that n is 128.
|
||||
}
|
||||
defer pool.Put(x, n)
|
||||
|
||||
// Work with x.
|
||||
}
|
||||
```
|
||||
|
||||
Pool allows you to pass specific options for constructing custom pool:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "github.com/gobwas/pool"
|
||||
|
||||
func main() {
|
||||
p := pool.Custom(
|
||||
pool.WithLogSizeMapping(), // Will ceil size n passed to Get(n) to nearest power of two.
|
||||
pool.WithLogSizeRange(64, 512), // Will reuse objects in logarithmic range [64, 512].
|
||||
pool.WithSize(65536), // Will reuse object with size 65536.
|
||||
)
|
||||
x, n := p.Get(1000) // Returns nil and 1000 because mapped size 1000 => 1024 is not reusing by the pool.
|
||||
defer pool.Put(x, n) // Will not reuse x.
|
||||
|
||||
// Work with x.
|
||||
}
|
||||
```
|
||||
|
||||
Note that there are few non-generic pooling implementations inside subpackages.
|
||||
|
||||
## pbytes
|
||||
|
||||
Subpackage `pbytes` is intended for `[]byte` reuse.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "github.com/gobwas/pool/pbytes"
|
||||
|
||||
func main() {
|
||||
bts := pbytes.GetCap(100) // Returns make([]byte, 0, 128).
|
||||
defer pbytes.Put(bts)
|
||||
|
||||
// Work with bts.
|
||||
}
|
||||
```
|
||||
|
||||
You can also create your own range for pooling:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "github.com/gobwas/pool/pbytes"
|
||||
|
||||
func main() {
|
||||
// Reuse only slices whose capacity is 128, 256, 512 or 1024.
|
||||
pool := pbytes.New(128, 1024)
|
||||
|
||||
bts := pool.GetCap(100) // Returns make([]byte, 0, 128).
|
||||
defer pool.Put(bts)
|
||||
|
||||
// Work with bts.
|
||||
}
|
||||
```
|
||||
|
||||
## pbufio
|
||||
|
||||
Subpackage `pbufio` is intended for `*bufio.{Reader, Writer}` reuse.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "github.com/gobwas/pool/pbufio"
|
||||
|
||||
func main() {
|
||||
bw := pbufio.GetWriter(os.Stdout, 100) // Returns bufio.NewWriterSize(128).
|
||||
defer pbufio.PutWriter(bw)
|
||||
|
||||
// Work with bw.
|
||||
}
|
||||
```
|
||||
|
||||
Like with `pbytes`, you can also create pool with custom reuse bounds.
|
||||
|
||||
|
||||
|
||||
[godoc-image]: https://godoc.org/github.com/gobwas/pool?status.svg
|
||||
[godoc-url]: https://godoc.org/github.com/gobwas/pool
|
87
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/generic.go
generated
vendored
Normal file
87
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/generic.go
generated
vendored
Normal file
|
@ -0,0 +1,87 @@
|
|||
package pool
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/gobwas/pool/internal/pmath"
|
||||
)
|
||||
|
||||
var DefaultPool = New(128, 65536)
|
||||
|
||||
// Get pulls object whose generic size is at least of given size. It also
|
||||
// returns a real size of x for further pass to Put(). It returns -1 as real
|
||||
// size for nil x. Size >-1 does not mean that x is non-nil, so checks must be
|
||||
// done.
|
||||
//
|
||||
// Note that size could be ceiled to the next power of two.
|
||||
//
|
||||
// Get is a wrapper around DefaultPool.Get().
|
||||
func Get(size int) (interface{}, int) { return DefaultPool.Get(size) }
|
||||
|
||||
// Put takes x and its size for future reuse.
|
||||
// Put is a wrapper around DefaultPool.Put().
|
||||
func Put(x interface{}, size int) { DefaultPool.Put(x, size) }
|
||||
|
||||
// Pool contains logic of reusing objects distinguishable by size in generic
|
||||
// way.
|
||||
type Pool struct {
|
||||
pool map[int]*sync.Pool
|
||||
size func(int) int
|
||||
}
|
||||
|
||||
// New creates new Pool that reuses objects which size is in logarithmic range
|
||||
// [min, max].
|
||||
//
|
||||
// Note that it is a shortcut for Custom() constructor with Options provided by
|
||||
// WithLogSizeMapping() and WithLogSizeRange(min, max) calls.
|
||||
func New(min, max int) *Pool {
|
||||
return Custom(
|
||||
WithLogSizeMapping(),
|
||||
WithLogSizeRange(min, max),
|
||||
)
|
||||
}
|
||||
|
||||
// Custom creates new Pool with given options.
|
||||
func Custom(opts ...Option) *Pool {
|
||||
p := &Pool{
|
||||
pool: make(map[int]*sync.Pool),
|
||||
size: pmath.Identity,
|
||||
}
|
||||
|
||||
c := (*poolConfig)(p)
|
||||
for _, opt := range opts {
|
||||
opt(c)
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
// Get pulls object whose generic size is at least of given size.
|
||||
// It also returns a real size of x for further pass to Put() even if x is nil.
|
||||
// Note that size could be ceiled to the next power of two.
|
||||
func (p *Pool) Get(size int) (interface{}, int) {
|
||||
n := p.size(size)
|
||||
if pool := p.pool[n]; pool != nil {
|
||||
return pool.Get(), n
|
||||
}
|
||||
return nil, size
|
||||
}
|
||||
|
||||
// Put takes x and its size for future reuse.
|
||||
func (p *Pool) Put(x interface{}, size int) {
|
||||
if pool := p.pool[size]; pool != nil {
|
||||
pool.Put(x)
|
||||
}
|
||||
}
|
||||
|
||||
type poolConfig Pool
|
||||
|
||||
// AddSize adds size n to the map.
|
||||
func (p *poolConfig) AddSize(n int) {
|
||||
p.pool[n] = new(sync.Pool)
|
||||
}
|
||||
|
||||
// SetSizeMapping sets up incoming size mapping function.
|
||||
func (p *poolConfig) SetSizeMapping(size func(int) int) {
|
||||
p.size = size
|
||||
}
|
65
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/internal/pmath/pmath.go
generated
vendored
Normal file
65
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/internal/pmath/pmath.go
generated
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
package pmath
|
||||
|
||||
const (
|
||||
bitsize = 32 << (^uint(0) >> 63)
|
||||
maxint = int(1<<(bitsize-1) - 1)
|
||||
maxintHeadBit = 1 << (bitsize - 2)
|
||||
)
|
||||
|
||||
// LogarithmicRange iterates from ceiled to power of two min to max,
|
||||
// calling cb on each iteration.
|
||||
func LogarithmicRange(min, max int, cb func(int)) {
|
||||
if min == 0 {
|
||||
min = 1
|
||||
}
|
||||
for n := CeilToPowerOfTwo(min); n <= max; n <<= 1 {
|
||||
cb(n)
|
||||
}
|
||||
}
|
||||
|
||||
// IsPowerOfTwo reports whether given integer is a power of two.
|
||||
func IsPowerOfTwo(n int) bool {
|
||||
return n&(n-1) == 0
|
||||
}
|
||||
|
||||
// Identity is identity.
|
||||
func Identity(n int) int {
|
||||
return n
|
||||
}
|
||||
|
||||
// CeilToPowerOfTwo returns the least power of two integer value greater than
|
||||
// or equal to n.
|
||||
func CeilToPowerOfTwo(n int) int {
|
||||
if n&maxintHeadBit != 0 && n > maxintHeadBit {
|
||||
panic("argument is too large")
|
||||
}
|
||||
if n <= 2 {
|
||||
return n
|
||||
}
|
||||
n--
|
||||
n = fillBits(n)
|
||||
n++
|
||||
return n
|
||||
}
|
||||
|
||||
// FloorToPowerOfTwo returns the greatest power of two integer value less than
|
||||
// or equal to n.
|
||||
func FloorToPowerOfTwo(n int) int {
|
||||
if n <= 2 {
|
||||
return n
|
||||
}
|
||||
n = fillBits(n)
|
||||
n >>= 1
|
||||
n++
|
||||
return n
|
||||
}
|
||||
|
||||
func fillBits(n int) int {
|
||||
n |= n >> 1
|
||||
n |= n >> 2
|
||||
n |= n >> 4
|
||||
n |= n >> 8
|
||||
n |= n >> 16
|
||||
n |= n >> 32
|
||||
return n
|
||||
}
|
43
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/option.go
generated
vendored
Normal file
43
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/option.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
package pool
|
||||
|
||||
import "github.com/gobwas/pool/internal/pmath"
|
||||
|
||||
// Option configures pool.
|
||||
type Option func(Config)
|
||||
|
||||
// Config describes generic pool configuration.
|
||||
type Config interface {
|
||||
AddSize(n int)
|
||||
SetSizeMapping(func(int) int)
|
||||
}
|
||||
|
||||
// WithSizeLogRange returns an Option that will add logarithmic range of
|
||||
// pooling sizes containing [min, max] values.
|
||||
func WithLogSizeRange(min, max int) Option {
|
||||
return func(c Config) {
|
||||
pmath.LogarithmicRange(min, max, func(n int) {
|
||||
c.AddSize(n)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// WithSize returns an Option that will add given pooling size to the pool.
|
||||
func WithSize(n int) Option {
|
||||
return func(c Config) {
|
||||
c.AddSize(n)
|
||||
}
|
||||
}
|
||||
|
||||
func WithSizeMapping(sz func(int) int) Option {
|
||||
return func(c Config) {
|
||||
c.SetSizeMapping(sz)
|
||||
}
|
||||
}
|
||||
|
||||
func WithLogSizeMapping() Option {
|
||||
return WithSizeMapping(pmath.CeilToPowerOfTwo)
|
||||
}
|
||||
|
||||
func WithIdentitySizeMapping() Option {
|
||||
return WithSizeMapping(pmath.Identity)
|
||||
}
|
106
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/pbufio/pbufio.go
generated
vendored
Normal file
106
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/pbufio/pbufio.go
generated
vendored
Normal file
|
@ -0,0 +1,106 @@
|
|||
// Package pbufio contains tools for pooling bufio.Reader and bufio.Writers.
|
||||
package pbufio
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
|
||||
"github.com/gobwas/pool"
|
||||
)
|
||||
|
||||
var (
|
||||
DefaultWriterPool = NewWriterPool(256, 65536)
|
||||
DefaultReaderPool = NewReaderPool(256, 65536)
|
||||
)
|
||||
|
||||
// GetWriter returns bufio.Writer whose buffer has at least size bytes.
|
||||
// Note that size could be ceiled to the next power of two.
|
||||
// GetWriter is a wrapper around DefaultWriterPool.Get().
|
||||
func GetWriter(w io.Writer, size int) *bufio.Writer { return DefaultWriterPool.Get(w, size) }
|
||||
|
||||
// PutWriter takes bufio.Writer for future reuse.
|
||||
// It does not reuse bufio.Writer which underlying buffer size is not power of
|
||||
// PutWriter is a wrapper around DefaultWriterPool.Put().
|
||||
func PutWriter(bw *bufio.Writer) { DefaultWriterPool.Put(bw) }
|
||||
|
||||
// GetReader returns bufio.Reader whose buffer has at least size bytes. It returns
|
||||
// its capacity for further pass to Put().
|
||||
// Note that size could be ceiled to the next power of two.
|
||||
// GetReader is a wrapper around DefaultReaderPool.Get().
|
||||
func GetReader(w io.Reader, size int) *bufio.Reader { return DefaultReaderPool.Get(w, size) }
|
||||
|
||||
// PutReader takes bufio.Reader and its size for future reuse.
|
||||
// It does not reuse bufio.Reader if size is not power of two or is out of pool
|
||||
// min/max range.
|
||||
// PutReader is a wrapper around DefaultReaderPool.Put().
|
||||
func PutReader(bw *bufio.Reader) { DefaultReaderPool.Put(bw) }
|
||||
|
||||
// WriterPool contains logic of *bufio.Writer reuse with various size.
|
||||
type WriterPool struct {
|
||||
pool *pool.Pool
|
||||
}
|
||||
|
||||
// NewWriterPool creates new WriterPool that reuses writers which size is in
|
||||
// logarithmic range [min, max].
|
||||
func NewWriterPool(min, max int) *WriterPool {
|
||||
return &WriterPool{pool.New(min, max)}
|
||||
}
|
||||
|
||||
// CustomWriterPool creates new WriterPool with given options.
|
||||
func CustomWriterPool(opts ...pool.Option) *WriterPool {
|
||||
return &WriterPool{pool.Custom(opts...)}
|
||||
}
|
||||
|
||||
// Get returns bufio.Writer whose buffer has at least size bytes.
|
||||
func (wp *WriterPool) Get(w io.Writer, size int) *bufio.Writer {
|
||||
v, n := wp.pool.Get(size)
|
||||
if v != nil {
|
||||
bw := v.(*bufio.Writer)
|
||||
bw.Reset(w)
|
||||
return bw
|
||||
}
|
||||
return bufio.NewWriterSize(w, n)
|
||||
}
|
||||
|
||||
// Put takes ownership of bufio.Writer for further reuse.
|
||||
func (wp *WriterPool) Put(bw *bufio.Writer) {
|
||||
// Should reset even if we do Reset() inside Get().
|
||||
// This is done to prevent locking underlying io.Writer from GC.
|
||||
bw.Reset(nil)
|
||||
wp.pool.Put(bw, writerSize(bw))
|
||||
}
|
||||
|
||||
// ReaderPool contains logic of *bufio.Reader reuse with various size.
|
||||
type ReaderPool struct {
|
||||
pool *pool.Pool
|
||||
}
|
||||
|
||||
// NewReaderPool creates new ReaderPool that reuses writers which size is in
|
||||
// logarithmic range [min, max].
|
||||
func NewReaderPool(min, max int) *ReaderPool {
|
||||
return &ReaderPool{pool.New(min, max)}
|
||||
}
|
||||
|
||||
// CustomReaderPool creates new ReaderPool with given options.
|
||||
func CustomReaderPool(opts ...pool.Option) *ReaderPool {
|
||||
return &ReaderPool{pool.Custom(opts...)}
|
||||
}
|
||||
|
||||
// Get returns bufio.Reader whose buffer has at least size bytes.
|
||||
func (rp *ReaderPool) Get(r io.Reader, size int) *bufio.Reader {
|
||||
v, n := rp.pool.Get(size)
|
||||
if v != nil {
|
||||
br := v.(*bufio.Reader)
|
||||
br.Reset(r)
|
||||
return br
|
||||
}
|
||||
return bufio.NewReaderSize(r, n)
|
||||
}
|
||||
|
||||
// Put takes ownership of bufio.Reader for further reuse.
|
||||
func (rp *ReaderPool) Put(br *bufio.Reader) {
|
||||
// Should reset even if we do Reset() inside Get().
|
||||
// This is done to prevent locking underlying io.Reader from GC.
|
||||
br.Reset(nil)
|
||||
rp.pool.Put(br, readerSize(br))
|
||||
}
|
13
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/pbufio/pbufio_go110.go
generated
vendored
Normal file
13
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/pbufio/pbufio_go110.go
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
// +build go1.10
|
||||
|
||||
package pbufio
|
||||
|
||||
import "bufio"
|
||||
|
||||
func writerSize(bw *bufio.Writer) int {
|
||||
return bw.Size()
|
||||
}
|
||||
|
||||
func readerSize(br *bufio.Reader) int {
|
||||
return br.Size()
|
||||
}
|
27
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/pbufio/pbufio_go19.go
generated
vendored
Normal file
27
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/pbufio/pbufio_go19.go
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
// +build !go1.10
|
||||
|
||||
package pbufio
|
||||
|
||||
import "bufio"
|
||||
|
||||
func writerSize(bw *bufio.Writer) int {
|
||||
return bw.Available() + bw.Buffered()
|
||||
}
|
||||
|
||||
// readerSize returns buffer size of the given buffered reader.
|
||||
// NOTE: current workaround implementation resets underlying io.Reader.
|
||||
func readerSize(br *bufio.Reader) int {
|
||||
br.Reset(sizeReader)
|
||||
br.ReadByte()
|
||||
n := br.Buffered() + 1
|
||||
br.Reset(nil)
|
||||
return n
|
||||
}
|
||||
|
||||
var sizeReader optimisticReader
|
||||
|
||||
type optimisticReader struct{}
|
||||
|
||||
func (optimisticReader) Read(p []byte) (int, error) {
|
||||
return len(p), nil
|
||||
}
|
24
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/pbytes/pbytes.go
generated
vendored
Normal file
24
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/pbytes/pbytes.go
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
// Package pbytes contains tools for pooling byte pool.
|
||||
// Note that by default it reuse slices with capacity from 128 to 65536 bytes.
|
||||
package pbytes
|
||||
|
||||
// DefaultPool is used by pacakge level functions.
|
||||
var DefaultPool = New(128, 65536)
|
||||
|
||||
// Get returns probably reused slice of bytes with at least capacity of c and
|
||||
// exactly len of n.
|
||||
// Get is a wrapper around DefaultPool.Get().
|
||||
func Get(n, c int) []byte { return DefaultPool.Get(n, c) }
|
||||
|
||||
// GetCap returns probably reused slice of bytes with at least capacity of n.
|
||||
// GetCap is a wrapper around DefaultPool.GetCap().
|
||||
func GetCap(c int) []byte { return DefaultPool.GetCap(c) }
|
||||
|
||||
// GetLen returns probably reused slice of bytes with at least capacity of n
|
||||
// and exactly len of n.
|
||||
// GetLen is a wrapper around DefaultPool.GetLen().
|
||||
func GetLen(n int) []byte { return DefaultPool.GetLen(n) }
|
||||
|
||||
// Put returns given slice to reuse pool.
|
||||
// Put is a wrapper around DefaultPool.Put().
|
||||
func Put(p []byte) { DefaultPool.Put(p) }
|
59
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/pbytes/pool.go
generated
vendored
Normal file
59
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/pbytes/pool.go
generated
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
// +build !pool_sanitize
|
||||
|
||||
package pbytes
|
||||
|
||||
import "github.com/gobwas/pool"
|
||||
|
||||
// Pool contains logic of reusing byte slices of various size.
|
||||
type Pool struct {
|
||||
pool *pool.Pool
|
||||
}
|
||||
|
||||
// New creates new Pool that reuses slices which size is in logarithmic range
|
||||
// [min, max].
|
||||
//
|
||||
// Note that it is a shortcut for Custom() constructor with Options provided by
|
||||
// pool.WithLogSizeMapping() and pool.WithLogSizeRange(min, max) calls.
|
||||
func New(min, max int) *Pool {
|
||||
return &Pool{pool.New(min, max)}
|
||||
}
|
||||
|
||||
// New creates new Pool with given options.
|
||||
func Custom(opts ...pool.Option) *Pool {
|
||||
return &Pool{pool.Custom(opts...)}
|
||||
}
|
||||
|
||||
// Get returns probably reused slice of bytes with at least capacity of c and
|
||||
// exactly len of n.
|
||||
func (p *Pool) Get(n, c int) []byte {
|
||||
if n > c {
|
||||
panic("requested length is greater than capacity")
|
||||
}
|
||||
|
||||
v, x := p.pool.Get(c)
|
||||
if v != nil {
|
||||
bts := v.([]byte)
|
||||
bts = bts[:n]
|
||||
return bts
|
||||
}
|
||||
|
||||
return make([]byte, n, x)
|
||||
}
|
||||
|
||||
// Put returns given slice to reuse pool.
|
||||
// It does not reuse bytes whose size is not power of two or is out of pool
|
||||
// min/max range.
|
||||
func (p *Pool) Put(bts []byte) {
|
||||
p.pool.Put(bts, cap(bts))
|
||||
}
|
||||
|
||||
// GetCap returns probably reused slice of bytes with at least capacity of n.
|
||||
func (p *Pool) GetCap(c int) []byte {
|
||||
return p.Get(0, c)
|
||||
}
|
||||
|
||||
// GetLen returns probably reused slice of bytes with at least capacity of n
|
||||
// and exactly len of n.
|
||||
func (p *Pool) GetLen(n int) []byte {
|
||||
return p.Get(n, n)
|
||||
}
|
121
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/pbytes/pool_sanitize.go
generated
vendored
Normal file
121
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/pbytes/pool_sanitize.go
generated
vendored
Normal file
|
@ -0,0 +1,121 @@
|
|||
// +build pool_sanitize
|
||||
|
||||
package pbytes
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"runtime"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const magic = uint64(0x777742)
|
||||
|
||||
type guard struct {
|
||||
magic uint64
|
||||
size int
|
||||
owners int32
|
||||
}
|
||||
|
||||
const guardSize = int(unsafe.Sizeof(guard{}))
|
||||
|
||||
type Pool struct {
|
||||
min, max int
|
||||
}
|
||||
|
||||
func New(min, max int) *Pool {
|
||||
return &Pool{min, max}
|
||||
}
|
||||
|
||||
// Get returns probably reused slice of bytes with at least capacity of c and
|
||||
// exactly len of n.
|
||||
func (p *Pool) Get(n, c int) []byte {
|
||||
if n > c {
|
||||
panic("requested length is greater than capacity")
|
||||
}
|
||||
|
||||
pageSize := syscall.Getpagesize()
|
||||
pages := (c+guardSize)/pageSize + 1
|
||||
size := pages * pageSize
|
||||
|
||||
bts := alloc(size)
|
||||
|
||||
g := (*guard)(unsafe.Pointer(&bts[0]))
|
||||
*g = guard{
|
||||
magic: magic,
|
||||
size: size,
|
||||
owners: 1,
|
||||
}
|
||||
|
||||
return bts[guardSize : guardSize+n]
|
||||
}
|
||||
|
||||
func (p *Pool) GetCap(c int) []byte { return p.Get(0, c) }
|
||||
func (p *Pool) GetLen(n int) []byte { return Get(n, n) }
|
||||
|
||||
// Put returns given slice to reuse pool.
|
||||
func (p *Pool) Put(bts []byte) {
|
||||
hdr := *(*reflect.SliceHeader)(unsafe.Pointer(&bts))
|
||||
ptr := hdr.Data - uintptr(guardSize)
|
||||
|
||||
g := (*guard)(unsafe.Pointer(ptr))
|
||||
if g.magic != magic {
|
||||
panic("unknown slice returned to the pool")
|
||||
}
|
||||
if n := atomic.AddInt32(&g.owners, -1); n < 0 {
|
||||
panic("multiple Put() detected")
|
||||
}
|
||||
|
||||
// Disable read and write on bytes memory pages. This will cause panic on
|
||||
// incorrect access to returned slice.
|
||||
mprotect(ptr, false, false, g.size)
|
||||
|
||||
runtime.SetFinalizer(&bts, func(b *[]byte) {
|
||||
mprotect(ptr, true, true, g.size)
|
||||
free(*(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
|
||||
Data: ptr,
|
||||
Len: g.size,
|
||||
Cap: g.size,
|
||||
})))
|
||||
})
|
||||
}
|
||||
|
||||
func alloc(n int) []byte {
|
||||
b, err := unix.Mmap(-1, 0, n, unix.PROT_READ|unix.PROT_WRITE|unix.PROT_EXEC, unix.MAP_SHARED|unix.MAP_ANONYMOUS)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func free(b []byte) {
|
||||
if err := unix.Munmap(b); err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func mprotect(ptr uintptr, r, w bool, size int) {
|
||||
// Need to avoid "EINVAL addr is not a valid pointer,
|
||||
// or not a multiple of PAGESIZE."
|
||||
start := ptr & ^(uintptr(syscall.Getpagesize() - 1))
|
||||
|
||||
prot := uintptr(syscall.PROT_EXEC)
|
||||
switch {
|
||||
case r && w:
|
||||
prot |= syscall.PROT_READ | syscall.PROT_WRITE
|
||||
case r:
|
||||
prot |= syscall.PROT_READ
|
||||
case w:
|
||||
prot |= syscall.PROT_WRITE
|
||||
}
|
||||
|
||||
_, _, err := syscall.Syscall(syscall.SYS_MPROTECT,
|
||||
start, uintptr(size), prot,
|
||||
)
|
||||
if err != 0 {
|
||||
panic(err.Error())
|
||||
}
|
||||
}
|
25
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/pool.go
generated
vendored
Normal file
25
trunk/3rdparty/srs-bench/vendor/github.com/gobwas/pool/pool.go
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Package pool contains helpers for pooling structures distinguishable by
|
||||
// size.
|
||||
//
|
||||
// Quick example:
|
||||
//
|
||||
// import "github.com/gobwas/pool"
|
||||
//
|
||||
// func main() {
|
||||
// // Reuse objects in logarithmic range from 0 to 64 (0,1,2,4,6,8,16,32,64).
|
||||
// p := pool.New(0, 64)
|
||||
//
|
||||
// buf, n := p.Get(10) // Returns buffer with 16 capacity.
|
||||
// if buf == nil {
|
||||
// buf = bytes.NewBuffer(make([]byte, n))
|
||||
// }
|
||||
// defer p.Put(buf, n)
|
||||
//
|
||||
// // Work with buf.
|
||||
// }
|
||||
//
|
||||
// There are non-generic implementations for pooling:
|
||||
// - pool/pbytes for []byte reuse;
|
||||
// - pool/pbufio for *bufio.Reader and *bufio.Writer reuse;
|
||||
//
|
||||
package pool
|
Loading…
Add table
Add a link
Reference in a new issue