153 lines
4.2 KiB
C
Executable File
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();
|
|
}
|