Files

387 lines
6.7 KiB
C++
Raw Permalink Normal View History

2026-03-28 16:54:11 +11:00
/***************************************************************************************
*
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
*
* By downloading, copying, installing or using the software you agree to this license.
* If you do not agree to this license, do not download, install,
* copy or use the software.
*
* Copyright (C) 2014-2024, Happytimesoft Corporation, all rights reserved.
*
* Redistribution and use in binary forms, with or without modification, are permitted.
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
* language governing permissions and limitations under the License.
*
****************************************************************************************/
#include "sys_inc.h"
#include "hqueue.h"
/***************************************************************************************/
HT_API HQUEUE * hqCreate(uint32 unit_num, uint32 unit_size, uint32 queue_mode)
{
uint32 q_len = unit_num * unit_size + sizeof(HQUEUE);
HQUEUE *phq = (HQUEUE *)malloc(q_len);
if (phq == NULL)
{
log_print(HT_LOG_ERR, "%s, malloc HQUEUE fail\r\n", __FUNCTION__);
return NULL;
}
phq->queue_mode = queue_mode;
phq->unit_size = unit_size;
phq->unit_num = unit_num;
phq->front = 0;
phq->rear = 0;
phq->count_put_full = 0;
phq->queue_buffer = sizeof(HQUEUE);
if (queue_mode & HQ_NO_EVENT)
{
phq->queue_nnulEvent = NULL;
phq->queue_nfulEvent = NULL;
phq->queue_putMutex = NULL;
}
else
{
phq->queue_nnulEvent = sys_os_create_sig();
phq->queue_nfulEvent = sys_os_create_sig();
phq->queue_putMutex = sys_os_create_mutex();
}
return phq;
}
HT_API void hqDelete(HQUEUE * phq)
{
if (phq == NULL)
{
return;
}
if (phq->queue_mode & HQ_NO_EVENT)
{
}
else
{
sys_os_destroy_sig_mutex(phq->queue_nnulEvent);
sys_os_destroy_sig_mutex(phq->queue_nfulEvent);
sys_os_destroy_sig_mutex(phq->queue_putMutex);
}
free(phq);
}
/***************************************************************************************/
void hqPutMutexEnter(HQUEUE * phq)
{
if ((phq->queue_mode & HQ_NO_EVENT) == 0)
{
sys_os_mutex_enter(phq->queue_putMutex);
}
}
void hqPutMutexLeave(HQUEUE * phq)
{
if ((phq->queue_mode & HQ_NO_EVENT) == 0)
{
sys_os_mutex_leave(phq->queue_putMutex);
}
}
HT_API BOOL hqBufPut(HQUEUE * phq, char * buf)
{
uint32 real_rear, queue_count;
char * ptr;
if (phq == NULL || buf == NULL)
{
return FALSE;
}
hqPutMutexEnter(phq);
hqBufPut_start:
queue_count = phq->rear - phq->front;
if (queue_count == (phq->unit_num - 1))
{
if ((phq->queue_mode & HQ_NO_EVENT) == 0)
{
if (phq->queue_mode & HQ_PUT_WAIT)
{
sys_os_sig_wait(phq->queue_nfulEvent);
goto hqBufPut_start;
}
else
{
phq->count_put_full++;
hqPutMutexLeave(phq);
// log_print(HT_LOG_ERR, "%s, queue_count=%d,full!!!\r\n", __FUNCTION__, queue_count);
return FALSE;
}
}
else
{
hqPutMutexLeave(phq);
return FALSE;
}
}
real_rear = phq->rear % phq->unit_num;
ptr = ((char *)phq) + phq->queue_buffer + real_rear*phq->unit_size;
memcpy((char *)ptr, buf, phq->unit_size);
phq->rear++;
if ((phq->queue_mode & HQ_NO_EVENT) == 0)
{
sys_os_sig_sign(phq->queue_nnulEvent);
}
hqPutMutexLeave(phq);
return TRUE;
}
HT_API BOOL hqBufGet(HQUEUE * phq, char * buf)
{
uint32 real_front;
if (phq == NULL || buf == NULL)
{
return FALSE;
}
hqBufGet_start:
if (phq->front == phq->rear)
{
if ((phq->queue_mode & HQ_NO_EVENT) == 0)
{
if (phq->queue_mode & HQ_GET_WAIT)
{
sys_os_sig_wait(phq->queue_nnulEvent);
goto hqBufGet_start;
}
else
{
return FALSE;
}
}
else
{
return FALSE;
}
}
real_front = phq->front % phq->unit_num;
memcpy(buf, ((char *)phq) + phq->queue_buffer + real_front*phq->unit_size, phq->unit_size);
phq->front++;
if ((phq->queue_mode & HQ_NO_EVENT) == 0)
{
sys_os_sig_sign(phq->queue_nfulEvent);
}
return TRUE;
}
HT_API BOOL hqBufIsEmpty(HQUEUE * phq)
{
if (phq == NULL)
{
return TRUE;
}
if (phq->front == phq->rear)
{
return TRUE;
}
return FALSE;
}
HT_API BOOL hqBufIsFull(HQUEUE * phq)
{
uint32 queue_count;
if (phq == NULL)
{
return FALSE;
}
queue_count = phq->rear - phq->front;
if (queue_count == (phq->unit_num - 1))
{
return TRUE;
}
return FALSE;
}
HT_API char * hqBufGetWait(HQUEUE * phq)
{
uint32 real_front;
char * ptr = NULL;
if (phq == NULL)
{
return NULL;
}
hqBufGet_start:
if (phq->front == phq->rear)
{
if ((phq->queue_mode & HQ_NO_EVENT) == 0)
{
if (phq->queue_mode & HQ_GET_WAIT)
{
sys_os_sig_wait(phq->queue_nnulEvent);
goto hqBufGet_start;
}
else
{
return NULL;
}
}
else
{
return NULL;
}
}
real_front = phq->front % phq->unit_num;
ptr = ((char *)phq) + phq->queue_buffer + real_front*phq->unit_size;
return ptr;
}
HT_API void hqBufGetWaitPost(HQUEUE * phq)
{
if (phq == NULL)
{
return;
}
phq->front++;
if ((phq->queue_mode & HQ_NO_EVENT) == 0)
{
sys_os_sig_sign(phq->queue_nfulEvent);
}
}
HT_API char * hqBufPutPtrWait(HQUEUE * phq)
{
uint32 real_rear,queue_count;
char * ptr;
if (phq == NULL)
{
return NULL;
}
hqPutMutexEnter(phq);
hqBufPutPtr_start:
queue_count = phq->rear - phq->front;
if (queue_count == (phq->unit_num - 1))
{
if ((phq->queue_mode & HQ_NO_EVENT) == 0)
{
if (phq->queue_mode & HQ_PUT_WAIT)
{
sys_os_sig_wait(phq->queue_nfulEvent);
goto hqBufPutPtr_start;
}
else
{
phq->count_put_full++;
hqPutMutexLeave(phq);
return FALSE;
}
}
else
{
hqPutMutexLeave(phq);
return FALSE;
}
}
real_rear = phq->rear % phq->unit_num;
ptr = ((char *)phq) + phq->queue_buffer + real_rear*phq->unit_size;
return ptr;
}
HT_API void hqBufPutPtrWaitPost(HQUEUE * phq, BOOL bPutFinish)
{
if (phq == NULL)
{
return;
}
if (bPutFinish)
{
phq->rear++;
}
if ((phq->queue_mode & HQ_NO_EVENT) == 0)
{
sys_os_sig_sign(phq->queue_nnulEvent);
}
hqPutMutexLeave(phq);
}
HT_API BOOL hqBufPeek(HQUEUE * phq, char * buf)
{
uint32 real_front;
if (phq == NULL || buf == NULL)
{
return FALSE;
}
hqBufPeek_start:
if (phq->front == phq->rear)
{
if ((phq->queue_mode & HQ_NO_EVENT) == 0)
{
if (phq->queue_mode & HQ_GET_WAIT)
{
sys_os_sig_wait(phq->queue_nnulEvent);
goto hqBufPeek_start;
}
else
{
return FALSE;
}
}
else
{
return FALSE;
}
}
real_front = phq->front % phq->unit_num;
memcpy(buf, ((char *)phq) + phq->queue_buffer + real_front*phq->unit_size, phq->unit_size);
return TRUE;
}