387 lines
6.7 KiB
C++
387 lines
6.7 KiB
C++
|
|
/***************************************************************************************
|
||
|
|
*
|
||
|
|
* 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;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|