fusion/common/kpacket.h

185 lines
5.1 KiB
C
Raw Permalink Normal View History

2025-08-05 07:53:44 +00:00
/*************************************************
File name : kpacket.h
Module : pal
Author : amir.liang
Version : 0.1
Created on : 2021-09-16
Description :
included files required by os environment
Modify History:
1. Date: Author: Modification:
20230424 amir use os_lock instead of mutex.
*************************************************/
#ifndef __PACKET_H__
#define __PACKET_H__
#include <stdint.h>
#include "hdef.h"
#include "hmutex.h"
#include "hatomic.h"
#ifndef OK
#define OK (char)(0)
#endif
#ifndef NG
#define NG (char)(1)
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*===========================================*/
/*1. do not use kpacket with stack memory */
/*2. payload address must be algin 4 */
/*===========================================*/
#define KPACKET_DEBUG 1U
#if KPACKET_DEBUG
#define KPACKET_LOG hlogd
#else
#define KPACKET_LOG(...)
#endif
#define OS_PACKET_MAGIC 0xcafe
/*
*kpacket_put_int: int推数据到value, pop_int对应有即可
*: kpacket_put_int(kp, 123); val = kpacket_pop_int(kp, -1) val应该是123
*/
typedef struct {
uint16_t checksum; /* crc16 , just for TLV, include OS_PACKET_MAGIC */
uint16_t magic; /* OS_PACKET_MAGIC */
uint16_t T; /*TLV T: 0~65535 */
uint32_t L; /*TLV L: total size of value */
char V[0]; /*TLV V: the addr of value */
}TLV;
TLV *TLV_init(char *buf, uint32_t cap);
typedef struct{
hatomic_t ref; /*引用计数, 创建时为1, 当减到值为0时将释放kpacket内存 */
uint32_t capacity; /*内存容量,主要是 value能存的数据大小 = sizeof(kpacket) + len(value) */
uint32_t offset; /*仅用于标识 value的offset*/
TLV tlv;
}kpacket;
/*
* packet_pool_size recommend 4K
* init
*/
void kpacket_init(uint32_t packet_pool_size);
/*
*
* checksum到kpacket, checksum
*/
uint16_t kpacket_checksum(kpacket *packet);
/*
*
* checksum kpacket
*/
uint16_t kpacket_calc_checksum(kpacket *packet);
/*
*
*/
kpacket *kpacket_slab_alloc(uint32_t size);
/*
*
*/
void kpacket_slab_free(kpacket *packet);
#define kpacket_inc(_packet) ({\
hatomic_inc(&_packet->ref);/*没锁,有风险*/\
KPACKET_LOG("%s packet:%p, inc_ref:%d\n", __func__, _packet, _packet->ref);\
})
#define kpacket_dec(_packet) ({\
if (_packet->ref == 0){\
hloge("%s Error... hv_free_packet:%p, dec_ref should not be:%d\n", __func__, _packet, _packet->ref);\
}\
hatomic_dec(&_packet->ref);/*没锁,可能有风险*/\
if (_packet->ref == 0){\
KPACKET_LOG("%s free_packet:%p, dec_ref:%d ..............\n", __func__, _packet, _packet->ref);\
kpacket_slab_free(_packet);/*os_packet_delete(_packet);*/\
}else KPACKET_LOG("%s :%p, dec_ref:%d\n", __func__, _packet, _packet->ref);\
})
#define os_packet_valid(__packet) ({int32_t _ret;\
if (__packet && __packet-->tlv.magic == OS_PACKET_MAGIC){\
_ret = 1;\
}else{\
KPACKET_LOG("%s err packet:%p(!NULL), packet magic:%X(=%X)\n",__func__, __packet, __packet?__packet-->tlv.magic:0, OS_PACKET_MAGIC);\
_ret = 0;\
}\
_ret;})
#define kpacket(_event, _capacity)({\
kpacket *_packet = kpacket_slab_alloc(sizeof(kpacket) + _capacity);\
if (_packet){\
_packet->tlv.magic = OS_PACKET_MAGIC;\
_packet->tlv.T = _event;\
_packet->ref = 1;\
_packet->capacity = _capacity;\
_packet->tlv.L = 0;\
_packet->offset = 0;\
}else{\
hloge("%s kpacket_create outofmemory", __func__);\
}\
_packet;})
/*do not call os_packet_delete normally, use atomic_dec(packet) instead */
#if 0
#define os_packet_delete(_hv_free_packet)({\
if (os_packet_valid(_hv_free_packet)){\
if (_hv_free_packet->ref == 0) {\
hv_free(_hv_free_packet);\
hloge("%s os_packet_hv_free packet:%p",__func__, _hv_free_packet);\
}else{\
hloge("%s os_packet_hv_free error packet->ref:%d",__func__, _hv_free_packet->ref);\
}\
}else{\
hloge("%s os_packet_hv_free error",__func__);\
}\
})
#endif
uint32_t kpacket_put_int(kpacket *p, int32_t val);
uint32_t kpacket_put_string(kpacket *p, const char *str);//including '\0'
uint32_t kpacket_put_data(kpacket *p, const char *data, uint32_t len);
uint32_t kpacket_put_data1data2(kpacket *p, const char *data, uint32_t len, const char *data2, uint32_t len2);
//data move to 'zero' and dataLen be 0
void kpacket_reset(kpacket *p);
uint32_t kpacket_get_freesize(const kpacket *p);
uint32_t kpacket_pop_int(kpacket *p_box, const int32_t defVal);
const char *kpacket_pop_string(kpacket *p_box, const char *defVal);
uint32_t kpacket_pop_data(kpacket *p_box, char **data);
uint32_t kpacket_pop_reset(kpacket *p_box);
void kpacket_dump(kpacket *p);
void kpacket_test(void);
#ifdef __cplusplus
}
#endif
#endif /*_OS_TYPE_H__ */