compiled a very basic patch for generating a sinewave with the heavycompiler
This commit is contained in:
136
hello-world/c/HvLightPipe.c
Normal file
136
hello-world/c/HvLightPipe.c
Normal file
@ -0,0 +1,136 @@
|
||||
/**
|
||||
* Copyright (c) 2014-2018 Enzien Audio Ltd.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "HvLightPipe.h"
|
||||
|
||||
#if __SSE__ || HV_SIMD_SSE
|
||||
#include <xmmintrin.h>
|
||||
#define hv_sfence() _mm_sfence()
|
||||
#elif __arm__ || HV_SIMD_NEON
|
||||
#if __ARM_ACLE
|
||||
#include <arm_acle.h>
|
||||
// https://msdn.microsoft.com/en-us/library/hh875058.aspx#BarrierRestrictions
|
||||
// http://doxygen.reactos.org/d8/d47/armintr_8h_a02be7ec76ca51842bc90d9b466b54752.html
|
||||
#define hv_sfence() __dmb(0xE) /* _ARM_BARRIER_ST */
|
||||
#elif defined(__GNUC__) && (__ARM_ARCH >= 7)
|
||||
#define hv_sfence() __asm__ volatile ("dmb 0xE":::"memory")
|
||||
#else
|
||||
// http://stackoverflow.com/questions/19965076/gcc-memory-barrier-sync-synchronize-vs-asm-volatile-memory
|
||||
#define hv_sfence() __sync_synchronize()
|
||||
#endif
|
||||
#elif HV_WIN
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684208(v=vs.85).aspx
|
||||
#define hv_sfence() _WriteBarrier()
|
||||
#else
|
||||
#define hv_sfence() __asm__ volatile("" : : : "memory")
|
||||
#endif
|
||||
|
||||
#define HLP_STOP 0
|
||||
#define HLP_LOOP 0xFFFFFFFF
|
||||
#define HLP_SET_UINT32_AT_BUFFER(a, b) (*((hv_uint32_t *) (a)) = (b))
|
||||
#define HLP_GET_UINT32_AT_BUFFER(a) (*((hv_uint32_t *) (a)))
|
||||
|
||||
hv_uint32_t hLp_init(HvLightPipe *q, hv_uint32_t numBytes) {
|
||||
if (numBytes > 0) {
|
||||
q->buffer = (char *) hv_malloc(numBytes);
|
||||
hv_assert(q->buffer != NULL);
|
||||
HLP_SET_UINT32_AT_BUFFER(q->buffer, HLP_STOP);
|
||||
} else {
|
||||
q->buffer = NULL;
|
||||
}
|
||||
q->writeHead = q->buffer;
|
||||
q->readHead = q->buffer;
|
||||
q->len = numBytes;
|
||||
q->remainingBytes = numBytes;
|
||||
return numBytes;
|
||||
}
|
||||
|
||||
void hLp_free(HvLightPipe *q) {
|
||||
hv_free(q->buffer);
|
||||
}
|
||||
|
||||
hv_uint32_t hLp_hasData(HvLightPipe *q) {
|
||||
hv_uint32_t x = HLP_GET_UINT32_AT_BUFFER(q->readHead);
|
||||
if (x == HLP_LOOP) {
|
||||
q->readHead = q->buffer;
|
||||
x = HLP_GET_UINT32_AT_BUFFER(q->readHead);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
char *hLp_getWriteBuffer(HvLightPipe *q, hv_uint32_t bytesToWrite) {
|
||||
char *const readHead = q->readHead;
|
||||
char *const oldWriteHead = q->writeHead;
|
||||
const hv_uint32_t totalByteRequirement = bytesToWrite + 2*sizeof(hv_uint32_t);
|
||||
|
||||
// check if there is enough space to write the data in the remaining
|
||||
// length of the buffer
|
||||
if (totalByteRequirement <= q->remainingBytes) {
|
||||
char *const newWriteHead = oldWriteHead + sizeof(hv_uint32_t) + bytesToWrite;
|
||||
|
||||
// check if writing would overwrite existing data in the pipe (return NULL if so)
|
||||
if ((oldWriteHead < readHead) && (newWriteHead >= readHead)) return NULL;
|
||||
else return (oldWriteHead + sizeof(hv_uint32_t));
|
||||
} else {
|
||||
// there isn't enough space, try looping around to the start
|
||||
if (totalByteRequirement <= q->len) {
|
||||
if ((oldWriteHead < readHead) || ((q->buffer + totalByteRequirement) > readHead)) {
|
||||
return NULL; // overwrite condition
|
||||
} else {
|
||||
q->writeHead = q->buffer;
|
||||
q->remainingBytes = q->len;
|
||||
HLP_SET_UINT32_AT_BUFFER(q->buffer, HLP_STOP);
|
||||
hv_sfence();
|
||||
HLP_SET_UINT32_AT_BUFFER(oldWriteHead, HLP_LOOP);
|
||||
return q->buffer + sizeof(hv_uint32_t);
|
||||
}
|
||||
} else {
|
||||
return NULL; // there isn't enough space to write the data
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void hLp_produce(HvLightPipe *q, hv_uint32_t numBytes) {
|
||||
hv_assert(q->remainingBytes >= (numBytes + 2*sizeof(hv_uint32_t)));
|
||||
q->remainingBytes -= (sizeof(hv_uint32_t) + numBytes);
|
||||
char *const oldWriteHead = q->writeHead;
|
||||
q->writeHead += (sizeof(hv_uint32_t) + numBytes);
|
||||
HLP_SET_UINT32_AT_BUFFER(q->writeHead, HLP_STOP);
|
||||
|
||||
// save everything before this point to memory
|
||||
hv_sfence();
|
||||
|
||||
// then save this
|
||||
HLP_SET_UINT32_AT_BUFFER(oldWriteHead, numBytes);
|
||||
}
|
||||
|
||||
char *hLp_getReadBuffer(HvLightPipe *q, hv_uint32_t *numBytes) {
|
||||
*numBytes = HLP_GET_UINT32_AT_BUFFER(q->readHead);
|
||||
char *const readBuffer = q->readHead + sizeof(hv_uint32_t);
|
||||
return readBuffer;
|
||||
}
|
||||
|
||||
void hLp_consume(HvLightPipe *q) {
|
||||
hv_assert(HLP_GET_UINT32_AT_BUFFER(q->readHead) != HLP_STOP);
|
||||
q->readHead += sizeof(hv_uint32_t) + HLP_GET_UINT32_AT_BUFFER(q->readHead);
|
||||
}
|
||||
|
||||
void hLp_reset(HvLightPipe *q) {
|
||||
q->writeHead = q->buffer;
|
||||
q->readHead = q->buffer;
|
||||
q->remainingBytes = q->len;
|
||||
memset(q->buffer, 0, q->len);
|
||||
}
|
||||
Reference in New Issue
Block a user