/* @(#)00       1.7  src/bos/kernel/sys/mbuf_pool.h, sysuipc, bos72X, x2021_50A7 11/3/21 12:17:03 */

#ifndef _SYS_MBUF_POOL_H_
#define _SYS_MBUF_POOL_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <sys/mbuf_base.h>

/* -------------------------------------------------------------------------------------
// Definitions
*/

#ifdef _KERNEL
#endif
#ifndef NET_CACHELINESIZE
#define NET_CACHELINESIZE   128
#endif
/* Options for the mclpGet function */
#define MPOOLGET_ALL        0x1         /* return the count of buffers or fail */
#define MPOOLGET_WAIT       0x2         /* ensure the count can be filled.     */
#define MPOOLGET_MIX        0x4         /* mix the buffers returned.           */
#define MPOOLGET_LARGEST    0x8         /* returns the largest chain available */

/* -------------------------------------------------------------------------------------
// Extrernal References
*/

#ifdef _KERNEL
extern void log_clust_traceback(struct mpool_debug *);
extern void mclpHideCluster(struct mbuf *);
extern void mclpHideClusterBase(struct mbuf *, int);
extern void mclpUnhideCluster(struct mbuf *, int);
#endif

struct mclContig;

/* =====================================================================================
// NAME:    mclContig
// DESC:    contains information about mbufs added to an mpool as a part of
//          mclpGrowBlock call.  The mbuf's clusters are all part of the same
//          contiguous block of memory which is freed when all the mbufs have been
//          freed; done when the pool they are in are freed.
// ==================================================================================== */

typedef struct mclContig
{
    caddr_t         mclcCB;                 /* addr of contiguous block             */
    uint32_t        mclcElemSize;           /* size of the elements of the block    */
    uint32_t        mclcElemCnt;            /* # of elements in the block           */
    memreg_t        mclcMemReg;             /* contains the mem reg corr for block  */

} mclContig_t;

/* =====================================================================================
// NAME:    mclBkt
// DESC:    mbuf cluster pool bucket definition
// ==================================================================================== */

#define EYEC_MCLBA  __EYEC8('m','c','l','b','A','','','')   /* "mclbA"     */
#define EYEC_MCLBF  __EYEC8('m','c','l','b','F','','','')   /* "mclbF"     */

typedef struct mclBkt
{
#ifdef _KERNEL
    Simple_lock     mclbLock;               /* serialize bucket usage               */
    char            mclbCacheLine[NET_CACHELINESIZE - sizeof(Simple_lock)];
    eye_catch8b_t   mclbEyec;               /* eye catcher                          */
#else
    long            mclbLock;
    char            mclbCacheLine[128 - sizeof(long)];
    uint64_t        mclbEyec;
#endif
    int             mclbElemCnt;            /* total # clusters in this bucket      */
    int             mclbOutCnt;             /* # of clusters given from bucket      */
    mbuf_t          *mclbHead;              /* pointer to next available cluster    */
    mbuf_t          *mclbTail;              /* pointer to last available cluster    */
    int             mclbMaxOutCnt;          /* max # of clusters given out          */

} mclBkt_t;

/* =====================================================================================
// NAME:    mclust_pool
// DESC:    mbuf cluster pool definition
// ==================================================================================== */

#define EYEC_MCLPA  __EYEC8('m','c','l','p','A','','','')   /* "mclpA"*/
#define EYEC_MCLPF  __EYEC8('m','c','l','p','F','','','')   /* "mclpF"*/

/* Flags for mpools */

#define MPOOL_CONTIGUOUS       0x1          /* Contiguous memory for the buffers        */
#define MPOOL_CONTIGREAL       0x2          /* Use contiguous real memory allocator     */
#define MPOOL_NO4KPAGES        0x4          /* Tell net_malloc() to not use 4KB pages   */
#define MPOOL_GROW_AFFINITY    0x8          /* Grow with affinitized memory             */

/*
// NOTE - Be very carefull when modifying this structure. The mclpCBufAddr is used
// in a macro called MPOOL_CBUF which is refernced by a bunch of drivers. To keep
// the binary compatability new elements can be added at the end of the structure.
*/
typedef struct mclust_pool
{
#ifdef _KERNEL
    DRW_lock        *mclpLock;              /* serialize pool usage                 */
    eye_catch8b_t   mclpEyec;
#else
    long            mclpLock;
    uint64_t        mclpEyec;
#endif
    ras_block_t     mclpRasb;               /* RAS block for the pool               */
    char            mclpRasbName[RAS_NAME_MAX]; /* RAS name                         */
    extDebug_t      mclpDebug;              /* debug                                */
    struct mclust_pool *mclpNext;           /* next pool in cluster pool list       */
    int             mclpLockIntr;           /* interrupt before locking             */
    boolean_t       mclpInUse;              /* mpool in use                         */
    int             mclpFlags;              /* flags for the pool                   */
    int             mclpFreedCnt;           /* # of clusters that have been freed   */
    int             mclpElemCnt;            /* total # of clusters in this pool     */
    int             mclpElemType;           /* type of data in this pool            */
    int             mclpElemSize;           /* size of data in this pool            */
    int             mclpCalls;              /* # of calls to allocate               */
    int             mclpFailed;             /* # of failed cluster allocation       */
    int             mclpWaitCnt;            /* number of processes waiting on       */
    int             mclpFetchBktIndex;      /* current fetch bucket index           */
    int             mclpNumBkt;             /* number of buckets used
                                               the mpool                            */
    tid_t           mclpQueued;             /* users queued for waiting             */
    tid_t           mclpWaiting;            /* user waiting for buffers from the
                                               bucket. When MPOOLGET_WAIT is set    */
    caddr_t         mclpCBufAddr;           /* continguous cluster buffer user for
                                               clusters in contiguous pools         */
    ulong           mclpID;                 /* user set identifier to id pools      */
    mclBkt_t        *mclpBkt;               /* table of buckets                     */
    int (*mclpUserFree)(struct mbuf *);
    boolean_t       dfreecheck;             /* Double free checking on?             */
    int             mclpGrowBktIndex;       /* current grow bucket index            */
    sradid_t        mclpSrad;               /* associated srad id                   */

} mclPool_t;

/* =====================================================================================
// NAME:    mclustpool_info
// DESC:    mbuf cluster pool info definition
// ==================================================================================== */

struct mclustpool_info
{
    ulong           numPools;
#ifdef _KERNEL
    simple_lock_data_t mclpLock;            /* serialize cluster pool list access   */
#else
    long            mclpLock;
#endif
    mclPool_t       *pool;                  /* cluster pool list                    */
};


/* =====================================================================================
// NAME:    aligned_lock_t
// DESC:    aligned lock definition
//          (The following should probably be under NETSYNC_LOCK)
// ==================================================================================== */

#define MBLOCK_HASHSZ  521 

typedef struct aligned_lock
{
    simple_lock_data_t lock;
    uint64_t counter;
    /* Keep each aligned_lock structure on its own cache line */
    char pad[128 - sizeof(simple_lock_data_t) - sizeof(uint64_t)];

} aligned_lock_t;

extern  aligned_lock_t mbuf_slock[MBLOCK_HASHSZ];


#ifdef __cplusplus
}
#endif

#endif /* _SYS_MBUF_POOL_H_ */
