initial commit
This commit is contained in:
2
mw/mmc/config.mk
Executable file
2
mw/mmc/config.mk
Executable file
@@ -0,0 +1,2 @@
|
||||
HEADERS+= $(MW_DIR)/mmc/*.h
|
||||
SRCDIRS+= $(MW_DIR)/mmc
|
||||
152
mw/mmc/mw_mmc.c
Executable file
152
mw/mmc/mw_mmc.c
Executable file
@@ -0,0 +1,152 @@
|
||||
#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();
|
||||
}
|
||||
31
mw/mmc/mw_mmc.h
Executable file
31
mw/mmc/mw_mmc.h
Executable file
@@ -0,0 +1,31 @@
|
||||
#ifndef _MMC_H_
|
||||
#define _MMC_H_
|
||||
#include "hloop.h"
|
||||
#include "kpacket.h"
|
||||
|
||||
// subscribe a event
|
||||
// param will be keep, can trans to handler
|
||||
uint32_t mmc_sub(uint16_t event, hevent_cb cb, hevent_priority_e priority);
|
||||
|
||||
|
||||
/*async event
|
||||
packet 会被mmc引用计数+1,然后回调完所有后-1
|
||||
如果, packet在外部异步回调,请在外部增/减引用
|
||||
*/
|
||||
uint32_t mmc_pub(kpacket *packet);
|
||||
|
||||
|
||||
//sync event, call directly, and return
|
||||
//uint32_t mmc_pub_sync(kpacket *packet);
|
||||
|
||||
|
||||
/* init mmc */
|
||||
uint32_t mmc_init(uint32_t mmc_queue_size);
|
||||
|
||||
//deinit mmc
|
||||
uint32_t mmc_deinit();
|
||||
|
||||
void mmc_test();
|
||||
|
||||
|
||||
#endif /* _MMC_H_ */
|
||||
Reference in New Issue
Block a user