📄 support.c
字号:
//==========================================================================//// src/ecos/support.c////==========================================================================//####BSDCOPYRIGHTBEGIN####//// -------------------------------------------//// Portions of this software may have been derived from OpenBSD, // FreeBSD or other sources, and are covered by the appropriate// copyright disclaimers included herein.//// Portions created by Red Hat are// Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.//// Copyright (C) 2002, 2003 Gary Thomas// Copyright (C) 2003 Andrew Lunn// -------------------------------------------////####BSDCOPYRIGHTEND####//==========================================================================//==========================================================================//// ecos/support.c//// eCos wrapper and support functions////==========================================================================//####BSDCOPYRIGHTBEGIN####//// -------------------------------------------//// Portions of this software may have been derived from OpenBSD or other sources,// and are covered by the appropriate copyright disclaimers included herein.//// -------------------------------------------////####BSDCOPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s): gthomas, hmt// Contributors: gthomas, hmt, andrew.lunn@ascom.ch// Date: 2000-01-10// Purpose: // Description: // ////####DESCRIPTIONEND####////==========================================================================// Support routines, etc., used by network code#include <sys/param.h>#include <sys/malloc.h>#include <sys/mbuf.h>#include <sys/domain.h>#include <sys/protosw.h>#include <sys/sockio.h>#include <sys/socket.h>#include <sys/socketvar.h>#include <net/if.h>#include <net/netisr.h>#include <cyg/infra/diag.h>#include <cyg/hal/hal_intr.h>#include <cyg/kernel/kapi.h>#include <cyg/hal/hal_if.h>#include <cyg/infra/cyg_ass.h>#ifdef CYGPKG_NET_INET6#include <netinet/in.h>#include <netinet6/in6_var.h>#endif#if !CYGPKG_NET_DRIVER_FRAMEWORK // Interface#error At least one network driver framework must be defined!#else#include <cyg/io/eth/netdev.h>// Define table boundariesCYG_HAL_TABLE_BEGIN( __NETDEVTAB__, netdev );CYG_HAL_TABLE_END( __NETDEVTAB_END__, netdev );CYG_HAL_TABLE_BEGIN( __NET_INIT_TAB__, _Net_inits );CYG_HAL_TABLE_END( __NET_INIT_TAB_END__, _Net_inits );extern struct init_tab_entry __NET_INIT_TAB__[], __NET_INIT_TAB_END__;// Used for system-wide "ticks per second"#undef ticksint hz = 100;int tick = 10000; // usec per "tick"volatile struct timeval ktime;int proc = 0; // unusedint proc0 = 0; // unusedvolatile struct timeval mono_time;// Low-level network debugging & logging#ifdef CYGPKG_NET_FREEBSD_LOGGINGint cyg_net_log_mask = CYGPKG_NET_FREEBSD_LOGGING;#endif#ifdef CYGPKG_NET_INET6#define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL+2048)#else#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL#endifstatic char netint_stack[STACK_SIZE];static cyg_thread netint_thread_data;static cyg_handle_t netint_thread_handle;cyg_flag_t netint_flags; #define NETISR_ANY 0xFFFFFFFF // Any possible bit...extern void cyg_test_exit(void); // TEMPvoidcyg_panic(const char *msg, ...){ cyg_uint32 old_ints; CYG_FAIL( msg ); HAL_DISABLE_INTERRUPTS(old_ints); diag_printf("PANIC: %s\n", msg); cyg_test_exit(); // FIXME}#define NET_MEMPOOL_SIZE roundup(CYGPKG_NET_MEM_USAGE/4,MSIZE)#define NET_MBUFS_SIZE roundup(CYGPKG_NET_MEM_USAGE/4,MSIZE)#define NET_CLUSTERS_SIZE roundup(CYGPKG_NET_MEM_USAGE/2,MCLBYTES)static unsigned char net_mempool_area[NET_MEMPOOL_SIZE];static cyg_mempool_var net_mem_pool;static cyg_handle_t net_mem;static unsigned char net_mbufs_area[NET_MBUFS_SIZE];static cyg_mempool_fix net_mbufs_pool;static cyg_handle_t net_mbufs;static unsigned char net_clusters_area[NET_CLUSTERS_SIZE];static cyg_mempool_fix net_clusters_pool;static cyg_handle_t net_clusters;static char net_clusters_refcnt[(NET_CLUSTERS_SIZE/MCLBYTES)+1];int nmbclusters = (NET_CLUSTERS_SIZE/MCLBYTES);#ifdef CYGDBG_NET_TIMING_STATSstatic struct net_stats stats_malloc, stats_free, stats_memcpy, stats_memset, stats_mbuf_alloc, stats_mbuf_free, stats_cluster_alloc;extern struct net_stats stats_in_cksum;// Display a number of ticks as microseconds// Note: for improved calculation significance, values are kept in ticks*1000static long rtc_resolution[] = CYGNUM_KERNEL_COUNTERS_RTC_RESOLUTION;static long ns_per_system_clock;static voidshow_ticks_in_us(cyg_uint32 ticks){ long long ns; ns_per_system_clock = 1000000/rtc_resolution[1]; ns = (ns_per_system_clock * ((long long)ticks * 1000)) / CYGNUM_KERNEL_COUNTERS_RTC_PERIOD; ns += 5; // for rounding to .01us diag_printf("%7d.%02d", (int)(ns/1000), (int)((ns%1000)/10));}voidshow_net_stats(struct net_stats *stats, const char *title){ int ave; ave = stats->total_time / stats->count; diag_printf("%s:\n", title); diag_printf(" count: %6d", stats->count); diag_printf(", min: "); show_ticks_in_us(stats->min_time); diag_printf(", max: "); show_ticks_in_us(stats->max_time); diag_printf(", total: "); show_ticks_in_us(stats->total_time); diag_printf(", ave: "); show_ticks_in_us(ave); diag_printf("\n"); // Reset stats memset(stats, 0, sizeof(*stats));}voidshow_net_times(void){ show_net_stats(&stats_malloc, "Net malloc"); show_net_stats(&stats_free, "Net free"); show_net_stats(&stats_mbuf_alloc, "Mbuf alloc"); show_net_stats(&stats_mbuf_free, "Mbuf free"); show_net_stats(&stats_cluster_alloc, "Cluster alloc"); show_net_stats(&stats_in_cksum, "Checksum"); show_net_stats(&stats_memcpy, "Net memcpy"); show_net_stats(&stats_memset, "Net memset");}#endif /* CYGDBG_NET_TIMING_STATS */ void *cyg_net_malloc(u_long size, int type, int flags){ void *res; START_STATS(); log(LOG_MDEBUG, "Net malloc[%d] = ", size); if (flags & M_NOWAIT) { res = cyg_mempool_var_try_alloc(net_mem, size); } else { res = cyg_mempool_var_alloc(net_mem, size); } if ((flags & M_ZERO) && res) { memset(res,0,size); } FINISH_STATS(stats_malloc); log(LOG_MDEBUG, "%p\n", res); return (res);}void cyg_net_free(caddr_t addr, int type){ START_STATS(); cyg_mempool_var_free(net_mem, addr); FINISH_STATS(stats_free);}#ifdef CYGDBG_NET_SHOW_MBUFSstruct mbuf *mbinfo[300];void cyg_net_show_mbufs(void){ int i; diag_printf(" MBUF : TYPE FLGS DATA[LEN] NEXT NEXTPKT\n"); for( i = 0; i < 300; i++ ) { struct mbuf *m = mbinfo[i]; char *type; if( m == 0 ) continue; switch( m->m_hdr.mh_type ) { case MT_FREE: type="FREE"; break; case MT_DATA: type="DATA"; break; case MT_HEADER: type="HEADER"; break; case MT_SONAME: type="SONAME"; break; case MT_FTABLE: type="FTABLE"; break; case MT_CONTROL: type="CONTROL"; break; case MT_OOBDATA: type="OOBDATA"; break; default: type="UNKNOWN"; break; } diag_printf("%08x: %s %04x %08x[%03d] %08x %08x\n", m, type, m->m_hdr.mh_flags, m->m_hdr.mh_data, m->m_hdr.mh_len, m->m_hdr.mh_next, m->m_hdr.mh_nextpkt); } diag_printf(" MBUF : TYPE FLGS DATA[LEN] NEXT NEXTPKT\n"); }#endifvoid *cyg_net_mbuf_alloc(void){ void *res; START_STATS(); log(LOG_MDEBUG, "Alloc mbuf = "); res = cyg_mempool_fix_try_alloc(net_mbufs);FINISH_STATS(stats_mbuf_alloc);#ifdef CYGDBG_NET_SHOW_MBUFS { int i; for( i = 0; i < (sizeof(mbinfo)/sizeof(mbinfo[0])); i++ ) if( mbinfo[i] == 0 ) { mbinfo[i] = (struct mbuf *)res; break; } }#endif // Check that this nastiness works OK CYG_ASSERT( dtom(res) == res, "dtom failed, base of mbuf" ); CYG_ASSERT( dtom((char *)res + MSIZE/2) == res, "dtom failed, mid mbuf" ); log(LOG_MDEBUG, "%p\n", res); return (res);}void *cyg_net_cluster_alloc(void){ void *res; START_STATS(); log(LOG_MDEBUG, "Allocate cluster = "); res = cyg_mempool_fix_try_alloc(net_clusters); FINISH_STATS(stats_cluster_alloc); log(LOG_MDEBUG, "%p\n", res); return res;}static struct vm_zone *vm_zones = (struct vm_zone *)NULL;vm_zone_t zinit(char *name, int size, int nentries, int flags, int zalloc){ void *res; vm_zone_t zone = (vm_zone_t)0; elem *p; log(LOG_MDEBUG, "zinit '%s', size: %d, num: %d, flags: %d, alloc: %d\n", name, size, nentries, flags, zalloc); res = cyg_mempool_var_try_alloc(net_mem, sizeof(struct vm_zone)); if (res) { zone = (vm_zone_t)res; res = cyg_mempool_var_try_alloc(net_mem, size*nentries); } if (!res) { log(LOG_MDEBUG, "Can't allocate memory for %s\n", name); panic("zinit: Out of memory\n"); } p = (elem *)res; zone->pool = (elem *)0; zone->elem_size = size; zone->name = name; zone->free = zone->total = nentries; zone->next = vm_zones; zone->alloc_tries = zone->alloc_fails = zone->alloc_frees = 0; vm_zones = zone; while (nentries-- > 0) { p->next = zone->pool; zone->pool = p; p = (elem *)((char *)p + size); } p = zone->pool;#if 0 while (p) { log(LOG_MDEBUG, "p: %p, next: %p\n", p, p->next); p = p->next; }#endif return zone;}void * zalloci(vm_zone_t zone){ elem *p; p = zone->pool; zone->alloc_tries++; if (p) { zone->pool = p->next;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -