#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include "ntp_machine.h"
#include "ntp_fp.h"
#include "ntp_stdlib.h"
#include "ntp_syslog.h"
#include "transmitbuff.h"
#define TRANSMIT_INIT 10
#define TRANSMIT_LOWAT 3
#define TRANSMIT_INC 5
#define TRANSMIT_TOOMANY 40
static volatile u_long full_transmitbufs = 0;
static volatile u_long free_transmitbufs = 0;
static struct transmitbuf *volatile freelist = NULL;
static struct transmitbuf *volatile fulllist = NULL;
static struct transmitbuf *volatile beginlist = NULL;
static u_long total_transmitbufs = 0;
static u_long lowater_additions = 0;
static struct transmitbuf initial_bufs[TRANSMIT_INIT];
#if defined(HAVE_SIGNALED_IO)
# define TRANSMIT_BLOCK_IO() BLOCKIO()
# define TRANSMIT_UNBLOCK_IO() UNBLOCKIO()
#elif defined(HAVE_IO_COMPLETION_PORT)
static CRITICAL_SECTION TransmitCritSection;
# define TRANSMIT_BLOCK_IO() EnterCriticalSection(&TransmitCritSection)
# define TRANSMIT_UNBLOCK_IO() LeaveCriticalSection(&TransmitCritSection)
#else
# define TRANSMIT_BLOCK_IO()
# define TRANSMIT_UNBLOCK_IO()
#endif
static void
initialise_buffer(struct transmitbuf *buff)
{
memset((char *) buff, 0, sizeof(struct transmitbuf));
#if defined HAVE_IO_COMPLETION_PORT
buff->iocompletioninfo.overlapped.hEvent = CreateEvent(NULL, FALSE,FALSE, NULL);
buff->wsabuf.len = 0;
buff->wsabuf.buf = (char *) &buff->pkt;
#endif
}
extern void
init_transmitbuff(void)
{
int i;
freelist = 0;
for (i = 0; i < TRANSMIT_INIT; i++)
{
initialise_buffer(&initial_bufs[i]);
initial_bufs[i].next = (struct transmitbuf *) freelist;
freelist = &initial_bufs[i];
}
fulllist = 0;
free_transmitbufs = total_transmitbufs = TRANSMIT_INIT;
full_transmitbufs = lowater_additions = 0;
#if defined(HAVE_IO_COMPLETION_PORT)
InitializeCriticalSection(&TransmitCritSection);
#endif
}
static void
create_buffers(void)
{
register struct transmitbuf *buf;
int i;
buf = (struct transmitbuf *)
emalloc(TRANSMIT_INC*sizeof(struct transmitbuf));
for (i = 0; i < TRANSMIT_INC; i++)
{
initialise_buffer(buf);
buf->next = (struct transmitbuf *) freelist;
freelist = buf;
buf++;
}
free_transmitbufs += TRANSMIT_INC;
total_transmitbufs += TRANSMIT_INC;
lowater_additions++;
}
extern void
free_transmit_buffer(
struct transmitbuf *rb
)
{
TRANSMIT_BLOCK_IO();
rb->next = freelist;
freelist = rb;
free_transmitbufs++;
TRANSMIT_UNBLOCK_IO();
}
extern struct transmitbuf *
get_free_transmit_buffer(void)
{
struct transmitbuf * buffer = NULL;
TRANSMIT_BLOCK_IO();
if (free_transmitbufs <= 0) {
create_buffers();
}
buffer = freelist;
freelist = buffer->next;
buffer->next = NULL;
--free_transmitbufs;
TRANSMIT_UNBLOCK_IO();
return buffer;
}