#include <stdio.h>
#include <time.h>
#include <limits.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <math.h>
#define UCHAR unsigned char
#define ULONG unsigned long
#define USHRT unsigned short
#define dbl double
/* Queue structure */
#define QUEUE_FULL_FLAG 1
#define QUEUE_EMPTY_FLAG -1
#define QUEUE_OK 0
//
#define BITS_ELE_KNT 12 // 4.096 elements numbered 0-4095
typedef struct {
UCHAR * pBuffer; // pointer to storage, 16 to 4096 elements
ULONG Tail : BITS_ELE_KNT; // # elements, with range of 0-4095
ULONG Head : BITS_ELE_KNT; // # elements, with range of 0-4095
ULONG EleBytes : 8 ; // sizeof(elements) with range of 0-256 bytes
USHRT EleKnt : BITS_ELE_KNT + 1 ; // 1 extra bit for # elements (1-4096)
USHRT IsFull : 1 ; // queue is full
USHRT IsEmpty : 1 ; // queue is empty
USHRT Unused : 1 ; // 16th bit of USHRT
} QUEUE_DESC;
// ---------------------------------------------------------------------------
// Function prototypes
QUEUE_DESC * Q_Init( QUEUE_DESC * Q, int BitsForEleKnt, int DataTypeSz) ;
int Q_Put( QUEUE_DESC * Q, UCHAR * pNew) ;
int Q_Get( UCHAR * pOld, QUEUE_DESC * Q) ;
// ---------------------------------------------------------------------------
QUEUE_DESC * Q_Init( QUEUE_DESC * Q, int BitsForEleKnt, int DataTypeSz) {
memset ( ( void * ) Q
, 0 , sizeof ( QUEUE_DESC
) ) ; //init flags and bit integers to zero Q
-> EleKnt
= ( USHRT
) pow ( 2.0 , BitsForEleKnt
) ; Q-> EleBytes = DataTypeSz;
Q-> Head = Q-> Tail = 0 ;
if ( NULL
== ( Q
-> pBuffer
= ( UCHAR
* ) calloc ( Q
-> EleKnt
, Q
-> EleBytes
) ) ) { return NULL;
} else {
return Q;
}
}
// ---------------------------------------------------------------------------
int Q_Put( QUEUE_DESC * Q, UCHAR * pNew)
{
memcpy ( Q
-> pBuffer
+ ( Q
-> Tail
* Q
-> EleBytes
) , pNew
, Q
-> EleBytes
) ;
if ( Q-> Tail == ( Q-> Head + Q-> EleKnt) ) {
Q-> Tail += 1 ;
return QUEUE_FULL_FLAG; // queue is full
}
Q-> Tail += 1 ;
return QUEUE_OK;
}
// ---------------------------------------------------------------------------
int Q_Get( UCHAR * pOld, QUEUE_DESC * Q)
{
memcpy ( pOld
, Q
-> pBuffer
+ ( Q
-> Head
* Q
-> EleBytes
) , Q
-> EleBytes
) ; Q-> Head += 1 ;
if ( Q-> Head == Q-> Tail) {
return QUEUE_EMPTY_FLAG; // queue Empty - nothing to get
}
return QUEUE_OK; // No errors
}
//
// ---------------------------------------------------------------------------
int main( void ) {
int i = 0 ;
QUEUE_DESC Queue, * Q;
if ( NULL == ( Q = Q_Init( & Queue, BITS_ELE_KNT, sizeof ( int ) ) ) ) {
printf ( "\n Program failed to initialize. Aborting.\n \n " ) ; return 0 ;
}
printf ( "Let's try to put 10.000 elements in a circular buffer of 4.096 elements.\n " ) ; printf ( "So, before start we have:\n " ) ; printf ( " Q->Head = %i, Q->Tail = %i\n " , Q
-> Head
, Q
-> Tail
) ; printf ( " Q->EleKnt = %i\n " , Q
-> EleKnt
) ;
for ( i = 0 ; i < 10000 ; i++ )
{
int dummy = i * i;
if ( QUEUE_FULL_FLAG == Q_Put( Q, ( UCHAR * ) & dummy) ) {
printf ( "Oh Crap. Queue became full at %i.\n " , i
) ; break ;
}
}
if ( i >= 10000 )
printf ( "WTF. Queue is still not full? BUT I JUST ADDED 10.000 ELEMENTS!? \n " ) ;
printf ( "After the loop we have the following values:\n " ) ; printf ( " Q->Head = %i, Q->Tail = %i\n " , Q
-> Head
, Q
-> Tail
) ;
printf ( "Note that 10000 mod 4096 = %i, and you overflowed the buffer %i times.\n " , 10000 % 4096 , 10000 / 4096 ) ;
return 0 ;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDx0aW1lLmg+CiNpbmNsdWRlIDxsaW1pdHMuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8bWFsbG9jLmg+CiNpbmNsdWRlIDxtZW1vcnkuaD4KI2luY2x1ZGUgPG1hdGguaD4KCiNkZWZpbmUgVUNIQVIgdW5zaWduZWQgY2hhcgojZGVmaW5lIFVMT05HIHVuc2lnbmVkIGxvbmcKI2RlZmluZSBVU0hSVCB1bnNpZ25lZCBzaG9ydAojZGVmaW5lIGRibCAgIGRvdWJsZQoKLyogUXVldWUgc3RydWN0dXJlICovCiNkZWZpbmUgUVVFVUVfRlVMTF9GTEFHIDEKI2RlZmluZSBRVUVVRV9FTVBUWV9GTEFHIC0xCiNkZWZpbmUgUVVFVUVfT0sgMAovLyAgCiNkZWZpbmUgQklUU19FTEVfS05UICAgIDEyICAvLyA0LjA5NiBlbGVtZW50cyBudW1iZXJlZCAwLTQwOTUKCnR5cGVkZWYgc3RydWN0ICB7CiAgICBVQ0hBUiAgICpwQnVmZmVyOyAgIC8vICBwb2ludGVyIHRvIHN0b3JhZ2UsIDE2IHRvIDQwOTYgZWxlbWVudHMKICAgIFVMT05HIFRhaWwgIDpCSVRTX0VMRV9LTlQ7ICAvLyAgIyBlbGVtZW50cywgd2l0aCByYW5nZSBvZiAwLTQwOTUKICAgIFVMT05HIEhlYWQgIDpCSVRTX0VMRV9LTlQ7ICAvLyAgIyBlbGVtZW50cywgd2l0aCByYW5nZSBvZiAwLTQwOTUKICAgIFVMT05HIEVsZUJ5dGVzICA6ODsgICAgIC8vICBzaXplb2YoZWxlbWVudHMpIHdpdGggcmFuZ2Ugb2YgMC0yNTYgYnl0ZXMKICAgIFVTSFJUIEVsZUtudCAgICA6QklUU19FTEVfS05UICsxOy8vIDEgZXh0cmEgYml0IGZvciAjIGVsZW1lbnRzICgxLTQwOTYpCiAgICBVU0hSVCAgIElzRnVsbCAgOjE7ICAgICAvLyBxdWV1ZSBpcyBmdWxsCiAgICBVU0hSVCAgIElzRW1wdHkgOjE7ICAgICAvLyBxdWV1ZSBpcyBlbXB0eQogICAgVVNIUlQgICBVbnVzZWQgIDoxOyAgICAgLy8gMTZ0aCBiaXQgb2YgVVNIUlQKfSAgIFFVRVVFX0RFU0M7CgovLyAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vICBGdW5jdGlvbiBwcm90b3R5cGVzClFVRVVFX0RFU0MgKlFfSW5pdChRVUVVRV9ERVNDICpRLCBpbnQgQml0c0ZvckVsZUtudCwgaW50IERhdGFUeXBlU3opOwppbnQgUV9QdXQoUVVFVUVfREVTQyAqUSwgVUNIQVIgKnBOZXcpOwppbnQgUV9HZXQoVUNIQVIgKnBPbGQsIFFVRVVFX0RFU0MgKlEpOwoKLy8gIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpRVUVVRV9ERVNDICpRX0luaXQoUVVFVUVfREVTQyAqUSwgaW50IEJpdHNGb3JFbGVLbnQsIGludCBEYXRhVHlwZVN6KSAgICB7CiAgICBtZW1zZXQoKHZvaWQgKilRLCAwLCBzaXplb2YoUVVFVUVfREVTQykpOy8vaW5pdCBmbGFncyBhbmQgYml0IGludGVnZXJzIHRvIHplcm8KICAgIFEtPkVsZUtudCAgID0gICAoVVNIUlQpcG93KDIuMCwgQml0c0ZvckVsZUtudCk7CiAgICBRLT5FbGVCeXRlcyA9ICAgRGF0YVR5cGVTejsKICAgIFEtPkhlYWQgPSBRLT5UYWlsID0gMDsKCQkKCWlmKE5VTEwgPT0gKFEtPnBCdWZmZXIgPSAoVUNIQVIgKiljYWxsb2MoUS0+RWxlS250LCBRLT5FbGVCeXRlcykpKSAgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfSAgIGVsc2UgICAgewogICAgICAgIHJldHVybiBROwogICAgfQp9CgovLyAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmludCBRX1B1dChRVUVVRV9ERVNDICpRLCBVQ0hBUiAqcE5ldykgICAKewogICAgbWVtY3B5KFEtPnBCdWZmZXIgKyAoUS0+VGFpbCAqIFEtPkVsZUJ5dGVzKSwgcE5ldywgUS0+RWxlQnl0ZXMpOwoKCWlmKFEtPlRhaWwgPT0gKFEtPkhlYWQgKyBRLT5FbGVLbnQpKSB7CiAgICAgICAgUS0+VGFpbCArPSAxOyAgIAogICAgICAgIHJldHVybiBRVUVVRV9GVUxMX0ZMQUc7IC8vICBxdWV1ZSBpcyBmdWxsCiAgICB9CgogICAgUS0+VGFpbCArPSAxOyAgIAogICAgcmV0dXJuIFFVRVVFX09LOyAKfQoKLy8gIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQppbnQgUV9HZXQoVUNIQVIgKnBPbGQsIFFVRVVFX0RFU0MgKlEpICAgCnsKICAgIG1lbWNweShwT2xkLCBRLT5wQnVmZmVyICsgKFEtPkhlYWQgKiBRLT5FbGVCeXRlcyksIFEtPkVsZUJ5dGVzKTsKICAgIFEtPkhlYWQgKz0gMTsgICAKCiAgICBpZihRLT5IZWFkID09IFEtPlRhaWwpICAgICAgewogICAgICAgIHJldHVybiBRVUVVRV9FTVBUWV9GTEFHOyAvLyBxdWV1ZSBFbXB0eSAtIG5vdGhpbmcgdG8gZ2V0CiAgICB9CgogICAgcmV0dXJuIFFVRVVFX09LOyAvLyBObyBlcnJvcnMKfQoKLy8KLy8gIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQppbnQgbWFpbih2b2lkKSAgICB7CgogICAgaW50IGkgPSAwOwoJUVVFVUVfREVTQyBRdWV1ZSwgKlE7CgogICAgaWYoTlVMTCA9PSAoUSA9IFFfSW5pdCgmUXVldWUsIEJJVFNfRUxFX0tOVCwgc2l6ZW9mKGludCkpKSkgewogICAgICAgIHByaW50ZigiXG5Qcm9ncmFtIGZhaWxlZCB0byBpbml0aWFsaXplLiBBYm9ydGluZy5cblxuIik7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgoJcHJpbnRmKCJMZXQncyB0cnkgdG8gcHV0IDEwLjAwMCBlbGVtZW50cyBpbiBhIGNpcmN1bGFyIGJ1ZmZlciBvZiA0LjA5NiBlbGVtZW50cy5cbiIpOwoJcHJpbnRmKCJTbywgYmVmb3JlIHN0YXJ0IHdlIGhhdmU6XG4iKTsKCXByaW50ZigiICBRLT5IZWFkID0gJWksIFEtPlRhaWwgPSAlaVxuIiwgUS0+SGVhZCwgUS0+VGFpbCk7CglwcmludGYoIiAgUS0+RWxlS250ID0gJWlcbiIsIFEtPkVsZUtudCk7CgkKICAgIGZvciAoaSA9IDA7IGkgPCAxMDAwMDsgaSsrKSAgICAKCXsKICAgICAgICBpbnQgZHVtbXkgPSBpICogaTsKICAgICAgICAKCQlpZihRVUVVRV9GVUxMX0ZMQUcgPT0gUV9QdXQoUSwgKFVDSEFSICopJmR1bW15KSkgICAgewogICAgICAgICAgICAKCQkJcHJpbnRmKCJPaCBDcmFwLiBRdWV1ZSBiZWNhbWUgZnVsbCBhdCAlaS5cbiIsIGkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CgoJaWYgKGkgPj0gMTAwMDApCgkJcHJpbnRmKCJXVEYuIFF1ZXVlIGlzIHN0aWxsIG5vdCBmdWxsPyBCVVQgSSBKVVNUIEFEREVEIDEwLjAwMCBFTEVNRU5UUyE/IFxuIik7CiAgICAKCXByaW50ZigiQWZ0ZXIgdGhlIGxvb3Agd2UgaGF2ZSB0aGUgZm9sbG93aW5nIHZhbHVlczpcbiIpOwoJcHJpbnRmKCIgIFEtPkhlYWQgPSAlaSwgUS0+VGFpbCA9ICVpXG4iLCBRLT5IZWFkLCBRLT5UYWlsKTsKCglwcmludGYoIk5vdGUgdGhhdCAxMDAwMCBtb2QgNDA5NiA9ICVpLCBhbmQgeW91IG92ZXJmbG93ZWQgdGhlIGJ1ZmZlciAlaSB0aW1lcy5cbiIsIDEwMDAwICUgNDA5NiwgMTAwMDAgLyA0MDk2KTsKCQogICAgcmV0dXJuIDA7Cn0=