intnetinline.h revision 2e514a2acf5a08f3afc939213fb824fd2d68fb7d
/* $Id$ */
/** @file
* INTNET - Internal Networking, Inlined Code. (DEV,++)
*
* This is all inlined because it's too tedious to create 2-3 libraries to
* contain it all. Requires C++ since variables and code is mixed as usual.
*/
/*
* Copyright (C) 2006-2010 Sun Microsystems, Inc.
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 USA or visit http://www.sun.com if you need
* additional information or have any questions.
*/
#ifndef ___VBox_intnetinline_h
#define ___VBox_intnetinline_h
#ifndef __cplusplus
# error "C++ only header."
#endif
/**
* Get the amount of space available for writing.
*
* @returns Number of available bytes.
* @param pRingBuf The ring buffer.
*/
{
return offRead <= offWriteInt
}
/**
* Checks if the ring has more for us to read.
*
* @returns Number of ready bytes.
* @param pRingBuf The ring buffer.
*/
{
return offRead != offWriteCom;
}
/**
* Gets the next frame to read.
*
* @returns Pointer to the next frame. NULL if done.
* @param pRingBuf The ring buffer.
*/
{
if (offRead == offWriteCom)
return NULL;
}
/**
* Get the amount of data ready for reading.
*
* @returns Number of ready bytes.
* @param pRingBuf The ring buffer.
*/
{
return offRead <= offWriteCom
? offWriteCom - offRead
}
/**
* Calculates the pointer to the frame.
*
* @returns Pointer to the start of the frame.
* @param pHdr Pointer to the packet header
* @param pBuf The buffer the header is within. Only used in strict builds.
*/
{
#ifdef VBOX_STRICT
#endif
return pu8;
}
/**
* Skips to the next (read) frame in the buffer.
*
* @param pRingBuf The ring buffer in question.
*/
{
/* skip the frame */
#ifdef INTNET_POISON_READ_FRAMES
#endif
}
/**
* Allocates a frame in the specified ring.
*
* @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
* @param pRingBuf The ring buffer.
* @param cbFrame The frame size.
* @param ppHdr Where to return the frame header.
* Don't touch this!
* @param ppvFrame Where to return the frame pointer.
*/
DECLINLINE(int) INTNETRingAllocateFrame(PINTNETRINGBUF pRingBuf, uint32_t cbFrame, PINTNETHDR *ppHdr, void **ppvFrame)
{
/*
* Validate input and adjust the input.
*/
if (offRead <= offWriteInt)
{
/*
* Try fit it all before the end of the buffer.
*/
{
return VERR_WRONG_ORDER; /* race */
Log2(("INTNETRingAllocateFrame: offWriteInt: %#x -> %#x (1) (offRead=%#x)\n", offWriteInt, offNew, offRead));
return VINF_SUCCESS;
}
/*
* Try fit the frame at the start of the buffer.
* (The header fits before the end of the buffer because of alignment.)
*/
AssertMsg(pRingBuf->offEnd - offWriteInt >= sizeof(INTNETHDR), ("offEnd=%x offWriteInt=%x\n", pRingBuf->offEnd, offWriteInt));
{
return VERR_WRONG_ORDER; /* race */
Log2(("INTNETRingAllocateFrame: offWriteInt: %#x -> %#x (2) (offRead=%#x)\n", offWriteInt, offNew, offRead));
return VINF_SUCCESS;
}
}
/*
* The reader is ahead of the writer, try fit it into that space.
*/
{
return VERR_WRONG_ORDER; /* race */
Log2(("INTNETRingAllocateFrame: offWriteInt: %#x -> %#x (3) (offRead=%#x)\n", offWriteInt, offNew, offRead));
return VINF_SUCCESS;
}
/* (it didn't fit) */
return VERR_BUFFER_OVERFLOW;
}
/**
* Commits a frame.
*
* Make sure to commit the frames in the order they've been allocated!
*
* @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
* @param pRingBuf The ring buffer.
* @param pHdr The frame header returned by
* INTNETRingAllocateFrame.
*/
{
/*
* Validate input and commit order.
*/
/*
* Figure out the offWriteCom for this packet and update the ring.
*/
+ cb;
{
}
Log2(("INTNETRingCommitFrame: offWriteCom: %#x -> %#x (offRead=%#x)\n", pRingBuf->offWriteCom, offWriteCom, pRingBuf->offReadX));
}
/**
* Writes a frame to the specified ring.
*
* Make sure you don't have any uncommitted frames when calling this function!
*
* @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
* @param pRingBuf The ring buffer.
* @param pvFrame The bits to write.
* @param cbFrame How much to write.
*/
{
/*
* Validate input.
*/
/*
* Align the size and read the volatile ring buffer variables.
*/
if (offRead <= offWriteInt)
{
/*
* Try fit it all before the end of the buffer.
*/
{
return VERR_WRONG_ORDER; /* race */
return VINF_SUCCESS;
}
/*
* Try fit the frame at the start of the buffer.
* (The header fits before the end of the buffer because of alignment.)
*/
AssertMsg(pRingBuf->offEnd - offWriteInt >= sizeof(INTNETHDR), ("offEnd=%x offWriteInt=%x\n", pRingBuf->offEnd, offWriteInt));
{
return VERR_WRONG_ORDER; /* race */
return VINF_SUCCESS;
}
}
/*
* The reader is ahead of the writer, try fit it into that space.
*/
{
return VERR_WRONG_ORDER; /* race */
return VINF_SUCCESS;
}
/* (it didn't fit) */
return VERR_BUFFER_OVERFLOW;
}
/**
* Reads the next frame in the buffer and moves the read cursor past it.
*
* @returns Size of the frame in bytes. 0 is returned if nothing in the buffer.
* @param pRingBuff The ring buffer to read from.
* @param pvFrameDst Where to put the frame. The caller is responsible for
* ensuring that there is sufficient space for the frame.
*
* @deprecated Bad interface, do NOT use it! Only for tstIntNetR0.
*/
{
if (offRead == offWriteCom)
return 0;
#ifdef INTNET_POISON_READ_FRAMES
#endif
/* skip the frame */
return cbFrame;
}
/**
* Initializes a buffer structure.
*
* @param pIntBuf The internal networking interface buffer. This
* expected to be cleared prior to calling this
* function.
* @param cbBuf The size of the whole buffer.
* @param cbRecv The receive size.
* @param cbSend The send size.
*/
DECLINLINE(void) INTNETBufInit(PINTNETBUF pIntBuf, uint32_t cbBuf, uint32_t cbRecv, uint32_t cbSend)
{
/* receive ring buffer. */
uint32_t offBuf = RT_ALIGN_32(sizeof(INTNETBUF), INTNETRINGBUF_ALIGNMENT) - RT_OFFSETOF(INTNETBUF, Recv);
/* send ring buffer. */
}
#endif