fusion/mw/mmc/mw_mmc.c

153 lines
4.2 KiB
C
Executable File

#include <stdlib.h>
#include <stdint.h>
#include "hthread.h"
#include "hlog.h"
#include "mw_mmc.h"
typedef struct {
hthread_t th[HEVENT_PRIORITY_SIZE]; /* in case of block by one only thread */
hloop_t *loop[HEVENT_PRIORITY_SIZE];
hmutex_t mutex;
uint8_t inited;
}mmc;
static mmc s_mmc_inst = {0};
static void mmc_atomic_inc(void *p){
kpacket *packet =(kpacket *)p;
kpacket_inc(packet);
}
static void mmc_atomic_dec(void *p){
kpacket *packet =(kpacket *)p;
kpacket_dec(packet);
}
static uint32_t mmc_get_type(void *p){
kpacket *packet =(kpacket *)p;
return packet->tlv.T;
}
HTHREAD_ROUTINE(mmc_thread){
hloop_t *loop = (hloop_t *)userdata;
hloop_run(loop);
return(NULL);
}
uint32_t mmc_pub(kpacket *packet){
const uint32_t idx = packet->tlv.T % HEVENT_PRIORITY_SIZE;
hloop_t* loop = s_mmc_inst.loop[idx];
if ( loop ){
hloop_mmc_pub_event(loop, packet);
return OK;
} else {
return NG;
}
}
/*
* priority not the same with loop[HEVENT_PRIORITY_SIZE]
**/
uint32_t mmc_sub(uint16_t event, hevent_cb cb, hevent_priority_e priority){
const uint32_t idx = event % HEVENT_PRIORITY_SIZE;
if (!s_mmc_inst.inited){
hmutex_init(&s_mmc_inst.mutex);
s_mmc_inst.inited = 1;
}
hmutex_lock(&s_mmc_inst.mutex);
hloop_t* loop = s_mmc_inst.loop[idx];
hthread_t th = s_mmc_inst.th[idx];
if (!th){
s_mmc_inst.th[idx]= hthread_create(mmc_thread, loop);
}
hloop_mmc_sub_event(loop, event, priority, cb);
hmutex_unlock(&s_mmc_inst.mutex);
return 0;
}
uint32_t mmc_init(uint32_t mmc_queue_size){
for (uint32_t i = 0; i<sizeof(s_mmc_inst.loop)/sizeof(s_mmc_inst.loop[0]); i++){
hloop_t* loop = s_mmc_inst.loop[i] = hloop_new(HLOOP_FLAG_AUTO_FREE);
if (!loop){
return NG;
}
hloop_mmc_init(loop, mmc_atomic_inc, mmc_atomic_dec, mmc_get_type, mmc_queue_size);
}
return OK;
}
uint32_t mmc_deinit(){
uint32_t err = 0;
for (hevent_priority_e idx = HEVENT_LOWEST_PRIORITY; idx < HEVENT_PRIORITY_SIZE; idx++ )
{
hloop_t* loop = s_mmc_inst.loop[idx];
if ( loop ) {
s_mmc_inst.loop[idx] = NULL;
hloop_stop(loop);
uint64_t start_ms = gettimeofday_ms();
if (hthread_join(s_mmc_inst.th[idx]) != 0) {
err = ESRCH;
hloge("%s hthread_join priority:%d %p", __func__, idx, s_mmc_inst.th[idx]);
}else {
hlogw("%s %u/%u hthread_join priority:%d %p elapsed:%ul ms", __func__, idx+1, HEVENT_PRIORITY_SIZE, idx, s_mmc_inst.th[idx], gettimeofday_ms() - start_ms);
}
}else{
hloge("%s not init hthread_join priority:%d %p", __func__, idx+1, s_mmc_inst.th[idx]);
}
}
return err;
}
static void on_mmc_events_low(hevent_t* ev) {
kpacket *p = (kpacket*)ev->userdata;
hlogd("%s event_type=%d userdata=%s\n", __func__, (int)ev->event_type, p->tlv.V);
}
static void on_mmc_events_normal(hevent_t* ev) {
kpacket *p = (kpacket*)ev->userdata;
hlogd("%s event_type=%d userdata=%s\n", __func__, (int)ev->event_type, p->tlv.V);
}
static void on_mmc_events_high(hevent_t* ev) {
kpacket *p = (kpacket*)ev->userdata;
hlogd("%s event_type=%d userdata=%s\n", __func__, (int)ev->event_type, p->tlv.V);
}
void mmc_test()
{
#define MMC_EVENT_QUEUE_INIT_SIZE 128
enum{
EVENT_1,
EVENT_2,
};
mmc_init(MMC_EVENT_QUEUE_INIT_SIZE);
mmc_sub(EVENT_1, on_mmc_events_low, HEVENT_LOWEST_PRIORITY);
mmc_sub(EVENT_1, on_mmc_events_normal, HEVENT_NORMAL_PRIORITY);
mmc_sub(EVENT_1, on_mmc_events_high, HEVENT_HIGHEST_PRIORITY);
kpacket *packet = kpacket(EVENT_1, 10);
kpacket_put_string(packet, "123456");
mmc_pub(packet);
kpacket_dec(packet);
hlogd("%s packet=%p\n", __func__, packet);
mmc_sub(EVENT_2, on_mmc_events_low, HEVENT_LOWEST_PRIORITY);
mmc_sub(EVENT_2, on_mmc_events_normal, HEVENT_NORMAL_PRIORITY);
mmc_sub(EVENT_2, on_mmc_events_high, HEVENT_HIGHEST_PRIORITY);
packet = kpacket(EVENT_2, 10);
kpacket_put_string(packet, "abcdefg");
mmc_pub(packet);
kpacket_dec(packet);
hlogd("%s packet=%p\n", __func__, packet);
hv_sleep(1);
mmc_deinit();
}