<commit_before>/*
 * iaxclient: a cross-platform IAX softphone library
 *
 * Copyrights:
 * Copyright (c) 1999-2000 <NAME> and <NAME>
 * Copyright (C) 2007, Wimba, Inc.
 *
 * Contributors:
 * <see below>
 * <NAME> <<EMAIL>>
 *
 * This program is free software, distributed under the terms of
 * the GNU Lesser (Library) General Public License.
 */

/*
 * Ring Buffer utility.
 *
 * Author: <NAME>, http://www.softsynth.com
 * modified for SMP safety on Mac OS X by <NAME>
 * modified for SMP safety on Linux by <NAME>
 * also, allowed for const where possible
 * Note that this is safe only for a single-thread reader and a
 * single-thread writer.
 *
 * Originally distributed with the PortAudio Portable Audio Library.
 * For more information see: http://www.portaudio.com
 * Copyright (c) 1999-2000 <NAME> and <NAME>
 *
 * 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.
 */

/*
 * The text above constitutes the entire PortAudio license; however,
 * the PortAudio community also makes the following non-binding requests:
 *
 * Any person wishing to distribute modifications to the Software is
 * requested to send the modifications to the original developer so that
 * they can be incorporated into the canonical version. It is also
 * requested that these non-binding requests be included along with the
 * license above.
 */

/**
 @file
 @ingroup common_src
*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

#include "ringbuffer.h"

/****************
 * First, we'll define some memory barrier primitives based on the system.
 * right now only OS X, FreeBSD, and Linux are supported. In addition to providing
 * memory barriers, these functions should ensure that data cached in registers
 * is written out to cache where it can be snooped by other CPUs. (ie, the volatile
 * keyword should not be required)
 *
 * the primitives that must be defined are:
 *
 * rb_FullMemoryBarrier()
 * rb_ReadMemoryBarrier()
 * rb_WriteMemoryBarrier()
 *
 ****************/

/* OSMemoryBarrier() is not portable to Mac OS X 10.3.9. We choose to do
 * the more portable, less correct thing here and just use assembly with
 * known bugs. The downside is that there may be some audio playback
 * issues on some Macs.
 */
#if defined(__APPLE__) && 0
#   include <libkern/OSAtomic.h>
    /* Here are the memory barrier functions. Mac OS X only provides
       full memory barriers, so the three types of barriers are the same. */
#   define rb_FullMemoryBarrier()  OSMemoryBarrier()
#   define rb_ReadMemoryBarrier()  OSMemoryBarrier()
#   define rb_WriteMemoryBarrier() OSMemoryBarrier()
#elif defined(__GNUC__)
    /* GCC understands volatile asm and "memory" to mean it
     * should not reorder memory read/writes */
#   if defined( __ppc__ )
#      define rb_FullMemoryBarrier()  asm volatile("sync":::"memory")
#      define rb_ReadMemoryBarrier()  asm volatile("sync":::"memory")
#      define rb_WriteMemoryBarrier() asm volatile("sync":::"memory")
#   elif defined( __i386__ ) || defined( __i486__ ) || defined( __i586__ ) || defined( __i686__ )
#      define rb_FullMemoryBarrier()  asm volatile("mfence":::"memory")
#      define rb_ReadMemoryBarrier()  asm volatile("lfence":::"memory")
#      define rb_WriteMemoryBarrier() asm volatile("sfence":::"memory")
#   else
#      ifdef ALLOW_SMP_DANGERS
#         warning Memory barriers not defined on this system or system unknown
#         warning For SMP safety, you should fix this.
#         define rb_FullMemoryBarrier()
#         define rb_ReadMemoryBarrier()
#         define rb_WriteMemoryBarrier()
#      else
#         error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed.
#      endif
#   endif
#elif defined(_MSC_VER)
#   include <intrin.h>
#   pragma intrinsic(_ReadWriteBarrier)
#   pragma intrinsic(_ReadBarrier)
#   pragma intrinsic(_WriteBarrier)
#   define rb_FullMemoryBarrier()  _ReadWriteBarrier()
#   define rb_ReadMemoryBarrier()  _ReadBarrier()
#   define rb_WriteMemoryBarrier() _WriteBarrier()
#else
#   ifdef ALLOW_SMP_DANGERS
#      ifdef _MSC_VER
#         pragma message("Memory barriers not defined on this system or system unknown")
#         pragma message("For SMP safety, you should fix this.")
#      else
#         warning Memory barriers not defined on this system or system unknown
#         warning For SMP safety, you should fix this.
#      endif
#      define rb_FullMemoryBarrier()
#      define rb_ReadMemoryBarrier()
#      define rb_WriteMemoryBarrier()
#   else
#      error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed.
#   endif
#endif

/***************************************************************************
 * Initialize FIFO.
 * numBytes must be power of 2, returns -1 if not.
 */
long rb_InitializeRingBuffer( rb_RingBuffer *rbuf, long numBytes, void *dataPtr )
{
    if( ((numBytes-1) & numBytes) != 0) return -1; /* Not Power of two. */
    rbuf->bufferSize = numBytes;
    rbuf->buffer = (char *)dataPtr;
    rb_FlushRingBuffer( rbuf );
    rbuf->bigMask = (numBytes*2)-1;
    rbuf->smallMask = (numBytes)-1;
    return 0;
}

/***************************************************************************
** Return number of bytes available for reading. */
long rb_GetRingBufferReadAvailable( rb_RingBuffer *rbuf )
{
    rb_ReadMemoryBarrier();
    return ( (rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask );
}
/***************************************************************************
** Return number of bytes available for writing. */
long rb_GetRingBufferWriteAvailable( rb_RingBuffer *rbuf )
{
    /* Since we are calling rb_GetRingBufferReadAvailable, we don't need an aditional MB */
    return ( rbuf->bufferSize - rb_GetRingBufferReadAvailable(rbuf));
}

/***************************************************************************
** Clear buffer. Should only be called when buffer is NOT being read. */
void rb_FlushRingBuffer( rb_RingBuffer *rbuf )<commit_msg>Do runtime detection of SSE2 for x86 variants when necessary.<commit_after>/*
 * iaxclient: a cross-platform IAX softphone library
 *
 * Copyrights:
 * Copyright (c) 1999-2000 <NAME> and <NAME>
 * Copyright (C) 2007, Wimba, Inc.
 *
 * Contributors:
 * <see below>
 * <NAME> <<EMAIL>>
 *
 * This program is free software, distributed under the terms of
 * the GNU Lesser (Library) General Public License.
 */

/*
 * Ring Buffer utility.
 *
 * Author: <NAME>, http://www.softsynth.com
 * modified for SMP safety on Mac OS X by <NAME>
 * modified for SMP safety on Linux by <NAME>
 * also, allowed for const where possible
 * Note that this is safe only for a single-thread reader and a
 * single-thread writer.
 *
 * Originally distributed with the PortAudio Portable Audio Library.
 * For more information see: http://www.portaudio.com
 * Copyright (c) 1999-2000 <NAME> and <NAME>
 *
 * 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.
 */

/*
 * The text above constitutes the entire PortAudio license; however,
 * the PortAudio community also makes the following non-binding requests:
 *
 * Any person wishing to distribute modifications to the Software is
 * requested to send the modifications to the original developer so that
 * they can be incorporated into the canonical version. It is also
 * requested that these non-binding requests be included along with the
 * license above.
 */

/**
 @file
 @ingroup common_src
*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

#include "ringbuffer.h"

/****************
 * First, we'll define some memory barrier primitives based on the system.
 * right now only OS X, FreeBSD, and Linux are supported. In addition to providing
 * memory barriers, these functions should ensure that data cached in registers
 * is written out to cache where it can be snooped by other CPUs. (ie, the volatile
 * keyword should not be required)
 *
 * the primitives that must be defined are:
 *
 * rb_FullMemoryBarrier()
 * rb_ReadMemoryBarrier()
 * rb_WriteMemoryBarrier()
 *
 ****************/

/* OSMemoryBarrier() is not portable to Mac OS X 10.3.9. We choose to do
 * the more portable, less correct thing here and just use assembly with
 * known bugs. The downside is that there may be some audio playback
 * issues on some Macs.
 */
#if defined(__APPLE__) && 0
#   include <libkern/OSAtomic.h>
    /* Here are the memory barrier functions. Mac OS X only provides
       full memory barriers, so the three types of barriers are the same. */
#   define rb_FullMemoryBarrier()  OSMemoryBarrier()
#   define rb_ReadMemoryBarrier()  OSMemoryBarrier()
#   define rb_WriteMemoryBarrier() OSMemoryBarrier()
#elif defined(__GNUC__)
    /* GCC understands volatile asm and "memory" to mean it
     * should not reorder memory read/writes */
#   if defined( __ppc__ )
#      define rb_FullMemoryBarrier()  asm volatile("sync":::"memory")
#      define rb_ReadMemoryBarrier()  asm volatile("sync":::"memory")
#      define rb_WriteMemoryBarrier() asm volatile("sync":::"memory")
#   elif defined( __SSE2__ )
#      define rb_FullMemoryBarrier()  asm volatile("mfence":::"memory")
#      define rb_ReadMemoryBarrier()  asm volatile("lfence":::"memory")
#      define rb_WriteMemoryBarrier() asm volatile("sfence":::"memory")
#   elif defined( __i386__ ) || defined( __i486__ ) || defined( __i586__ ) || defined( __i686__ )
#      define DO_X86_RUNTIME_CPU_DETECTION
#      define rb_FullMemoryBarrier()  if ( have_sse2 ) asm volatile("mfence":::"memory")
#      define rb_ReadMemoryBarrier()  if ( have_sse2 ) asm volatile("lfence":::"memory")
#      define rb_WriteMemoryBarrier() if ( have_sse2 ) asm volatile("sfence":::"memory")
#   else
#      ifdef ALLOW_SMP_DANGERS
#         warning Memory barriers not defined on this system or system unknown
#         warning For SMP safety, you should fix this.
#         define rb_FullMemoryBarrier()
#         define rb_ReadMemoryBarrier()
#         define rb_WriteMemoryBarrier()
#      else
#         error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed.
#      endif
#   endif
#elif defined(_MSC_VER)
#   include <intrin.h>
#   pragma intrinsic(_ReadWriteBarrier)
#   pragma intrinsic(_ReadBarrier)
#   pragma intrinsic(_WriteBarrier)
#   define rb_FullMemoryBarrier()  _ReadWriteBarrier()
#   define rb_ReadMemoryBarrier()  _ReadBarrier()
#   define rb_WriteMemoryBarrier() _WriteBarrier()
#else
#   ifdef ALLOW_SMP_DANGERS
#      ifdef _MSC_VER
#         pragma message("Memory barriers not defined on this system or system unknown")
#         pragma message("For SMP safety, you should fix this.")
#      else
#         warning Memory barriers not defined on this system or system unknown
#         warning For SMP safety, you should fix this.
#      endif
#      define rb_FullMemoryBarrier()
#      define rb_ReadMemoryBarrier()
#      define rb_WriteMemoryBarrier()
#   else
#      error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed.
#   endif
#endif

#ifdef DO_X86_RUNTIME_CPU_DETECTION
#define cpuid(func, ax, bx, cx, dx)			\
	__asm__ __volatile__ ("xchgl\t%%ebx, %1\n\t"	\
	   "cpuid\n\t"					\
	   "xchgl\t%%ebx, %1\n\t"			\
	   : "=a" (ax), "=r" (bx), "=c" (cx), "=d" (dx)	\
	   : "0" (func))

static int have_sse2 = 0;
#endif

/***************************************************************************
 * Initialize FIFO.
 * numBytes must be power of 2, returns -1 if not.
 */
long rb_InitializeRingBuffer( rb_RingBuffer *rbuf, long numBytes, void *dataPtr )
{
#ifdef DO_X86_RUNTIME_CPU_DETECTION
    /* See http://softpixel.com/~cwright/programming/simd/cpuid.php
     * for a good description of how all this works.
     */
    int a, b, c, d;
    cpuid(1, a, b, c, d);
    have_sse2 = d & (1 << 26);
#endif

    if( ((numBytes-1) & numBytes) != 0) return -1; /* Not Power of two. */
    rbuf->bufferSize = numBytes;
    rbuf->buffer = (char *)dataPtr;
    rb_FlushRingBuffer( rbuf );
    rbuf->bigMask = (numBytes*2)-1;
    rbuf->smallMask = (numBytes)-1;
    return 0;
}

/***************************************************************************
** Return number of bytes available for reading. */
long rb_GetRingBufferReadAvailable( rb_RingBuffer *rbuf )
{
    rb_ReadMemoryBarrier();
    return ( (rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask );
}
/***************************************************************************
** Return number of bytes available for writing. */
long rb_GetRingBufferWriteAvailable( rb_RingBuffer *rbuf )
{
    /* Since we are calling rb_GetRingBufferReadAvailable, we don't need an aditional MB */
    return ( rbuf->bufferSize - rb_GetRingBufferReadAvailable(rbuf));
}

/***************************************************************************
** Clear buffer. Should only be called when buffer is NOT being read. */
void rb_FlushRingBuffer( rb_RingBuffer *rbuf )
{'fraction_non_alphanumeric': 0.13144363876071194, 'fraction_numerical': 0.007580751483190508, 'mean_word_length': 3.9643324607329844, 'pattern_counts': {'":': 15, '<': 39, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1628040', 'n_tokens_mistral': 4454, 'n_tokens_neox': 4216, 'n_words': 1666}