📄 unixlib.c
字号:
/* unixLib.c - UNIX kernel compatability library *//* Copyright 1984-1994 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02n,25nov97,vin changed mBufClGet() to netTupleGet().02m,14nov97,vin added panic hook.02l,08mar97,vin added hashinit() for pcb hash look ups (FREEBSD 2.2.1).02k,03dec96,vin added _netMalloc(..) & _netFree(..) which use network buffers02j,19mar95,dvs removed tron references.02i,15nov94,tmk added 29k fix from philm02h,07nov94,tmk added MC68LC040 support.02g,31oct94,kdl merge cleanup.02f,02aug94,tpr added MC68060 cpu support.02e,09jun93,hdn added a support for I80X8602d,29jul92,smb moved perror() to fioLib.c.02c,17jun92,jwt removed SPARC from !PORTABLE list - it no longer works.02b,16jun92,jwt added SPARC to !PORTABLE list; fixed 02a version number.02a,26may92,rrr the tree shuffle -changed includes to have absolute path from h/01z,17oct91,yao added support for CPU32.01y,04oct91,rrr passed through the ansification filter -changed includes to have absolute path from h/ -fixed #else and #endif -changed VOID to void -changed copyright notice01x,26aug91,rrr clean up function decls01w,23jul91,hdn added conditional macro for optimized TRON codes.01v,26apr91,hdn modified to use portable version of checksum routine.01u,26jun90,jcf added semSplSemInit (). Changed splSem to mutex.01t,20mar90,jcf added timeout of WAIT_FOREVER to semTake calls.01s,18mar90,hjb ifdef's to use optimized assembly checksum routine for 68k.01r,20aug89,gae #if'd out un-portable in_cksum.01q,16apr89,gae updated to 4.3BSD.01p,15oct88,dnw changed name of sleep() to ksleep() to avoid confusion with C library routine of same name. changed 'panic' to not suspend unless panicSuspend=TRUE.01o,22jun88,dnw removed ovbcopy(), copyin(), copyout(), and imin() which are now macros in systm.h. made spl...() use taskIdCurrent directly. made spl...() return 0/1 for "previous level" instead of task id.01n,29may88,dnw removed bcmp() and bzero() now in bLib. changed to v4 names.01m,04may88,jcf changed splSem to splSemId, and sem calls for new semLib.01l,28jan88,jcf made kernel independent.01k,23jan88,rdc brought back spl routines because of size issues.01j,04jan88,rdc made spl{net,imp,x} macro's in systm.h01i,17nov87,dnw removed printStatus from perror.01h,13nov87,rdc added perror;01g,22oct87,ecs delinted.01f,02may87,dnw added suspend to panic().01e,03apr87,ecs added copyright.01d,02apr87,jlf delinted.01c,27feb87,dnw change myTaskId() to vxMyTaskId().01b,22dec86,dnw added bcmp.01a,28jul86,rdc written.*//*DESCRIPTIONThis library provides routines that simulate or replace Unix kernel functionsthat are used in the network code. This includes the spl...() processorlevel locking routines, wakeup() and sleep() (renamed ksleep() to avoidconfusion with the C library routine called sleep()), perror() and panic(),and a checksum routine.*/#include "vxWorks.h"#include "semLib.h"#include "sys/types.h"#include "net/mbuf.h"#include "taskLib.h"#include "netinet/in.h"#include "netinet/in_systm.h"#include "lstLib.h"#include "net/systm.h"#include "logLib.h"#include "intLib.h"/* local variables */LOCAL SEMAPHORE splSem; /* the semaphore used by splnet, splimp, etc *//* global variables */BOOL panicSuspend; /* TRUE = suspend task causing panic */int splTid; /* owner of network processor level semaphore */SEM_ID splSemId = &splSem; /* spl mutex semaphore id */int mutexOptionsUnixLib = SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE;FUNCPTR _panicHook = NULL; /* panicHook for error recovery mechanism *//********************************************************************************* splSemInit - initialize the semaphore used by splnet, splimp, etc.** This routine is called by netLibInit () to initialize the spl semaphore.** NOMANUAL*/void splSemInit () { semMInit (&splSem, mutexOptionsUnixLib); }/******************************************************************************** splnet - set network processor level** splnet may be used to insure mutual exclusion among processes which* share common network data structures. In UNIXland, this is done by* setting the processor interrupt level. Here in VxWorksLand, however,* we use a simple semaphore mechanism. splx should be called after* completion of the critical section. We must check first to see if we're* already at network level.** RETURNS: previous "processor level"*/int splnet () { if ((ULONG) taskIdCurrent == splTid) return (1); semTake (splSemId, WAIT_FOREVER); splTid = (ULONG) taskIdCurrent; return (0); }/********************************************************************************* splimp - set imp processor level** This routine is indentical to splnet().* Currently, all network interlocking uses the same network semaphore.** RETURNS: previous "processor level"*/int splimp () { if ((ULONG) taskIdCurrent == splTid) return (1); semTake (splSemId, WAIT_FOREVER); splTid = (ULONG) taskIdCurrent; return (0); }/********************************************************************************* splx - set processor level** splx is used in UNIX to restore the processor level.* It is used in VxWorks in conjunction with splnet() and splimp() to provide* mutual exclusion of network data structures. splx marks the end of the* critical section.*/void splx (x) int x; /* processor level to restore */ { if (x == 0) { splTid = 0; semGive (splSemId); } }/********************************************************************************* ksleep - put a process to sleep** In Unix, processes can sleep on any value (typically an address).* In VxWorks, we substitute a semaphore mechanism so sleep()* calls have to be changed to provide the address of a semaphore.** Note: In Unix there are two "sleep" routines. In the kernel, the sleep* routine causes a process to block until a wakeup is done on the same* value that sleep was called with. This routine, and the wakeup routine* below, are replacements for that mechanism. However, in the C library* there is another sleep() routine that will suspend a process for a* specified number of seconds. Since VxWorks users porting an application* may have calls to the latter but not the former, there is potential for* vast confusion. Thus this routine has been renamed "ksleep" ("kernel sleep")* and all calls to it in network code have been changed.*/void ksleep (semId) SEM_ID semId; { BOOL hadSplSem; /* first see if we've got the network semaphore (splSemId); * if so, give it, and then take it back when we are awakened. */ hadSplSem = (splTid == (ULONG) taskIdCurrent); if (hadSplSem) { splTid = 0; semGive (splSemId); } semTake (semId, WAIT_FOREVER); if (hadSplSem) { semTake (splSemId, WAIT_FOREVER); splTid = (ULONG) taskIdCurrent; } }/********************************************************************************* wakeup - wakeup a sleeping process*/void wakeup (semId) SEM_ID semId; { semGive (semId); }#ifdef unixLib_PORTABLE/********************************************************************************* _insque - insert node in list after specified node.** Portable version of _insque ().*/void _insque (pNode, pPrev) NODE *pNode; NODE *pPrev; { NODE *pNext; pNext = pPrev->next; pPrev->next = pNode; pNext->previous = pNode; pNode->next = pNext; pNode->previous = pPrev; }/********************************************************************************* _remque - remove specified node in list.** Portable version of _remque ().*/void _remque (pNode) NODE *pNode; { pNode->previous->next = pNode->next; pNode->next->previous = pNode->previous; }#endif /* unixLib_PORTABLE *//********************************************************************************* panic - something is very wrong** panic simply logs a message to the console prepended with "panic".* If the panic occurs at task level, the current task is suspended.*/void panic (msg) char *msg; { /* execute the panic hook if one exists */ if (_panicHook != NULL) { (*_panicHook) (msg); return; } logMsg ("panic: %s\n", (int)msg, 0,0,0,0,0); if (!intContext () && panicSuspend) taskSuspend (0); }/********************************************************************************* _netMalloc - allocates network buffers** This function allocates the relevant cluster and returns the * the pointer to the memory allocated.* * INTERNAL* The first 4 bytes of the cluster allocated hold a back pointer to the mBlk* The actual cluster size allocated is the user requested size + size of * mBlk pointer to pointer.** NOMANUAL** RETURNS: char pointer /NULL */char * _netMalloc ( int bufSize, /* size of the buffer to get */ UCHAR type, /* type of mbuf to allocate */ int canWait /* M_WAIT/M_DONTWAIT */ ) { FAST struct mbuf * pMblk; FAST struct mbuf ** pPtrMblk; pMblk = netTupleGet (_pNetSysPool, (bufSize + sizeof(struct mbuf *)), canWait, type, TRUE); if (pMblk != NULL) { pPtrMblk = mtod(pMblk, struct mbuf **); *pPtrMblk = pMblk; pMblk->m_data += sizeof(struct mbuf **); return (mtod(pMblk, char *)); } else return (NULL); }/********************************************************************************* _netFree - frees network buffers** This function allocates the relevant cluster and returns the * the pointer to the memory allocated.* * INTERNAL* The first 4 bytes of the cluster allocated hold a back pointer to the mBlk* The actual cluster size allocated is the user requested size + 4.* Since the mBlk will retain the type,m_free() will automatically free the * relevant type** NOMANUAL** RETURNS: pointer/NULL */void _netFree ( char * pBuf /* pointer to buffer to free */ ) { if (pBuf != NULL) (void)m_free (*((struct mbuf **)(pBuf - sizeof(struct mbuf **)))); }/********************************************************************************* hashinit - initialize a hash table of a given size.** This function initializes the hashtable of a given number of elements.* It returns a pointer to the hash mask. * * NOMANUAL** RETURNS: pointer/NULL */void * hashinit ( int elements, /* number of elements in the hash table */ int type, /* type of entries PCB/IFADDR etc */ u_long * hashmask /* ptr to the hash mask */ ) { long hashsize; int ix; LIST_HEAD(generic, generic) *hashtbl; if (elements <= 0) panic("hashinit: bad elements"); for (hashsize = 1; hashsize <= elements; hashsize <<= 1) continue; hashsize >>= 1; hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl)); for (ix = 0; ix < hashsize; ix++) LIST_INIT(&hashtbl[ix]); *hashmask = hashsize - 1; return (hashtbl); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -