📄 support.c
字号:
}
log(LOG_MDEBUG, "zalloci from %s => %p\n", zone->name, p);
return (void *)p;
}
void
zfreei(vm_zone_t zone, void *item)
{
elem *p = (elem *)item;
log(LOG_MDEBUG, "zfreei to %s <= %p\n", zone->name, p);
p->next = zone->pool;
zone->pool = p;
zone->free++;
zone->alloc_frees++;
}
static void
cyg_kmem_init(void)
{
unsigned char *p;
#ifdef CYGPKG_NET_DEBUG
diag_printf("Network stack using %d bytes for misc space\n", NET_MEMPOOL_SIZE);
diag_printf(" %d bytes for mbufs\n", NET_MBUFS_SIZE);
diag_printf(" %d bytes for mbuf clusters\n", NET_CLUSTERS_SIZE);
#endif
cyg_mempool_var_create(&net_mempool_area,
NET_MEMPOOL_SIZE,
&net_mem,
&net_mem_pool);
// Align the mbufs on MSIZE boudaries so that dtom() can work.
p = (unsigned char *)(((long)(&net_mbufs_area) + MSIZE - 1) & ~(MSIZE-1));
cyg_mempool_fix_create(p,
((&(net_mbufs_area[NET_MBUFS_SIZE])) - p) & ~(MSIZE-1),
MSIZE,
&net_mbufs,
&net_mbufs_pool);
cyg_mempool_fix_create(&net_clusters_area,
NET_CLUSTERS_SIZE,
MCLBYTES,
&net_clusters,
&net_clusters_pool);
mbutl = (struct mbuf *)&net_clusters_area;
mclrefcnt = net_clusters_refcnt;
}
void cyg_kmem_print_stats( void )
{
cyg_mempool_info info;
struct vm_zone *zone;
diag_printf( "Network stack mbuf stats:\n" );
diag_printf( " mbufs %ld, clusters %ld, free clusters %ld\n",
mbstat.m_mbufs, /* mbufs obtained from page pool */
mbstat.m_clusters, /* clusters obtained from page pool */
/* mbstat.m_spare, */ /* spare field */
mbstat.m_clfree /* free clusters */
);
diag_printf( " Failed to get %ld times\n"
" Waited to get %ld times\n"
" Drained queues to get %ld times\n",
mbstat.m_drops, /* times failed to find space */
mbstat.m_wait, /* times waited for space */
mbstat.m_drain /* times drained protocols for space */
/* mbstat.m_mtypes[256]; type specific mbuf allocations */
);
zone = vm_zones;
while (zone) {
diag_printf("VM zone '%s':\n", zone->name);
diag_printf(" Total: %d, Free: %d, Allocs: %d, Frees: %d, Fails: %d\n",
zone->total, zone->free,
zone->alloc_tries, zone->alloc_frees, zone->alloc_fails);
zone = zone->next;
}
cyg_mempool_var_get_info( net_mem, &info );
diag_printf( "Misc mpool: total %7d, free %7d, max free block %d\n",
info.totalmem,
info.freemem,
info.maxfree
);
cyg_mempool_fix_get_info( net_mbufs, &info );
diag_printf( "Mbufs pool: total %7d, free %7d, blocksize %4d\n",
info.totalmem,
info.freemem,
info.blocksize
);
cyg_mempool_fix_get_info( net_clusters, &info );
diag_printf( "Clust pool: total %7d, free %7d, blocksize %4d\n",
info.totalmem,
info.freemem,
info.blocksize
);
}
// This API is for our own automated network tests. It's not in any header
// files because it's not at all supported.
int cyg_net_get_mem_stats( int which, cyg_mempool_info *p )
{
CYG_CHECK_DATA_PTR( p, "Bad pointer to mempool_info" );
CYG_ASSERT( 0 <= which, "Mempool selector underflow" );
CYG_ASSERT( 2 >=which, "Mempool selector overflow" );
if ( p )
switch ( which ) {
case 0:
cyg_mempool_var_get_info( net_mem, p );
break;
case 1:
cyg_mempool_fix_get_info( net_mbufs, p );
break;
case 2:
cyg_mempool_fix_get_info( net_clusters, p );
break;
default:
return 0;
}
return (int)p;
}
int
cyg_mtocl(u_long x)
{
int res;
res = (((u_long)(x) - (u_long)mbutl) >> MCLSHIFT);
return res;
}
struct mbuf *
cyg_cltom(u_long x)
{
struct mbuf *res;
res = (struct mbuf *)((caddr_t)((u_long)mbutl + ((u_long)(x) << MCLSHIFT)));
return res;
}
externC void
net_memcpy(void *d, void *s, int n)
{
START_STATS();
memcpy(d, s, n);
FINISH_STATS(stats_memcpy);
}
externC void
net_memset(void *s, int v, int n)
{
START_STATS();
memset(s, v, n);
FINISH_STATS(stats_memset);
}
// Rather than bring in the whole BSD 'random' code...
int
arc4random(void)
{
cyg_uint32 res;
static unsigned long seed = 0xDEADB00B;
HAL_CLOCK_READ(&res); // Not so bad... (but often 0..N where N is small)
seed = ((seed & 0x007F00FF) << 7) ^
((seed & 0x0F80FF00) >> 8) ^ // be sure to stir those low bits
(res << 13) ^ (res >> 9); // using the clock too!
return (int)seed;
}
void
get_random_bytes(void *buf, size_t len)
{
unsigned long ranbuf, *lp;
lp = (unsigned long *)buf;
while (len > 0) {
ranbuf = arc4random();
*lp++ = ranbuf;
len -= sizeof(ranbuf);
}
}
int
read_random_unlimited(void *buf, size_t len)
{
get_random_bytes(buf, len);
return len;
}
void read_random(void *buf, size_t len)
{
CYG_ASSERT(0 == (len & ~3), "Only multiple of words allowed");
get_random_bytes(buf, len);
}
void
microtime(struct timeval *tp)
{
*tp = ktime;
log(LOG_DEBUG, "%s: = %ld.%ld\n", __FUNCTION__, tp->tv_sec, tp->tv_usec);
ktime.tv_usec++; // In case clock isn't running yet
}
void
getmicrotime(struct timeval *tp)
{
*tp = ktime;
log(LOG_DEBUG, "%s: = %ld.%ld\n", __FUNCTION__, tp->tv_sec, tp->tv_usec);
ktime.tv_usec++; // In case clock isn't running yet
}
void
getmicrouptime(struct timeval *tp)
{
*tp = ktime;
log(LOG_DEBUG, "%s: = %ld.%ld\n", __FUNCTION__, tp->tv_sec, tp->tv_usec);
ktime.tv_usec++; // In case clock isn't running yet
}
// Taken from kern/kern_clock.c
/*
* Compute number of ticks in the specified amount of time.
*/
#ifndef LONG_MAX
#define LONG_MAX 0x7FFFFFFF
#endif
int
tvtohz(struct timeval *tv)
{
register unsigned long ticks;
register long sec, usec;
/*
* If the number of usecs in the whole seconds part of the time
* difference fits in a long, then the total number of usecs will
* fit in an unsigned long. Compute the total and convert it to
* ticks, rounding up and adding 1 to allow for the current tick
* to expire. Rounding also depends on unsigned long arithmetic
* to avoid overflow.
*
* Otherwise, if the number of ticks in the whole seconds part of
* the time difference fits in a long, then convert the parts to
* ticks separately and add, using similar rounding methods and
* overflow avoidance. This method would work in the previous
* case but it is slightly slower and assumes that hz is integral.
*
* Otherwise, round the time difference down to the maximum
* representable value.
*
* If ints have 32 bits, then the maximum value for any timeout in
* 10ms ticks is 248 days.
*/
sec = tv->tv_sec;
usec = tv->tv_usec;
if (usec < 0) {
sec--;
usec += 1000000;
}
if (sec < 0) {
#ifdef DIAGNOSTIC
if (usec > 0) {
sec++;
usec -= 1000000;
}
printf("tvotohz: negative time difference %ld sec %ld usec\n",
sec, usec);
#endif
ticks = 1;
} else if (sec <= LONG_MAX / 1000000)
ticks = (sec * 1000000 + (unsigned long)usec + (tick - 1))
/ tick + 1;
else if (sec <= LONG_MAX / hz)
ticks = sec * hz
+ ((unsigned long)usec + (tick - 1)) / tick + 1;
else
ticks = LONG_MAX;
if (ticks > INT_MAX)
ticks = INT_MAX;
return ((int)ticks);
}
void
get_mono_time(void)
{
panic("get_mono_time");
}
void
csignal(pid_t pgid, int signum, uid_t uid, uid_t euid)
{
panic("csignal");
}
int
bcmp(const void *_p1, const void *_p2, size_t len)
{
int res = 0;
unsigned char *p1 = (unsigned char *)_p1;
unsigned char *p2 = (unsigned char *)_p2;
while (len-- > 0) {
res = *p1++ - *p2++;
if (res) break;
}
return res;
}
int
copyout(const void *s, void *d, size_t len)
{
memcpy(d, s, len);
return 0;
}
int
copyin(const void *s, void *d, size_t len)
{
memcpy(d, s, len);
return 0;
}
void
ovbcopy(const void *s, void *d, size_t len)
{
memmove(d, s, len);
}
// ------------------------------------------------------------------------
// THE NETWORK THREAD ITSELF
//
// Network software interrupt handler
// This function is run as a separate thread to allow
// processing of network events (mostly incoming packets)
// at "user level" instead of at interrupt time.
//
// The actual handlers are 'registered' at system startup
//
// The set of handlers
static netisr_t *_netisr_handlers[NETISR_MAX+1];
struct ifqueue ipintrq;
#ifdef INET6
struct ifqueue ip6intrq;
#endif
char *hostname = "eCos_node";
// Register a 'netisr' handler for a given level
int
register_netisr(int level, netisr_t *fun)
{
CYG_ASSERT(level <= NETISR_MAX, "invalid netisr level");
CYG_ASSERT(_netisr_handlers[level] == 0, "re-registered netisr");
_netisr_handlers[level] = fun;
return 0; // ignored
}
//int unregister_netisr __P((int));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -