unixLib.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:13k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* unixLib.c - UNIX kernel compatability library */
  2. /* Copyright 1984 - 2001 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 02o,15oct01,rae  merge from truestack ver 02r, base 02n (SPR 32626 etc.)
  8. 02n,25nov97,vin  changed mBufClGet() to netTupleGet().
  9. 02m,14nov97,vin  added panic hook.
  10. 02l,08mar97,vin  added hashinit() for pcb hash look ups (FREEBSD 2.2.1).
  11. 02k,03dec96,vin  added _netMalloc(..) & _netFree(..) which use network buffers
  12. 02j,19mar95,dvs  removed tron references.
  13. 02i,15nov94,tmk  added 29k fix from philm
  14. 02h,07nov94,tmk  added MC68LC040 support.
  15. 02g,31oct94,kdl  merge cleanup.
  16. 02f,02aug94,tpr  added MC68060 cpu support.
  17. 02e,09jun93,hdn  added a support for I80X86
  18. 02d,29jul92,smb  moved perror() to fioLib.c.
  19. 02c,17jun92,jwt  removed SPARC from !PORTABLE list - it no longer works.
  20. 02b,16jun92,jwt  added SPARC to !PORTABLE list; fixed 02a version number.
  21. 02a,26may92,rrr  the tree shuffle
  22.   -changed includes to have absolute path from h/
  23. 01z,17oct91,yao  added support for CPU32.
  24. 01y,04oct91,rrr  passed through the ansification filter
  25.   -changed includes to have absolute path from h/
  26.   -fixed #else and #endif
  27.   -changed VOID to void
  28.   -changed copyright notice
  29. 01x,26aug91,rrr  clean up function decls
  30. 01w,23jul91,hdn  added conditional macro for optimized TRON codes.
  31. 01v,26apr91,hdn  modified to use portable version of checksum routine.
  32. 01u,26jun90,jcf  added semSplSemInit ().  Changed splSem to mutex.
  33. 01t,20mar90,jcf  added timeout of WAIT_FOREVER to semTake calls.
  34. 01s,18mar90,hjb  ifdef's to use optimized assembly checksum routine for 68k.
  35. 01r,20aug89,gae  #if'd out un-portable in_cksum.
  36. 01q,16apr89,gae  updated to 4.3BSD.
  37. 01p,15oct88,dnw  changed name of sleep() to ksleep() to avoid confusion
  38.    with C library routine of same name.
  39.  changed 'panic' to not suspend unless panicSuspend=TRUE.
  40. 01o,22jun88,dnw  removed ovbcopy(), copyin(), copyout(), and imin() which
  41.    are now macros in systm.h.
  42.  made spl...() use taskIdCurrent directly.
  43.  made spl...() return 0/1 for "previous level" instead of
  44.    task id.
  45. 01n,29may88,dnw  removed bcmp() and bzero() now in bLib.
  46.  changed to v4 names.
  47. 01m,04may88,jcf  changed splSem to splSemId, and sem calls for new semLib.
  48. 01l,28jan88,jcf  made kernel independent.
  49. 01k,23jan88,rdc  brought back spl routines because of size issues.
  50. 01j,04jan88,rdc  made spl{net,imp,x} macro's in systm.h
  51. 01i,17nov87,dnw  removed printStatus from perror.
  52. 01h,13nov87,rdc  added perror;
  53. 01g,22oct87,ecs  delinted.
  54. 01f,02may87,dnw  added suspend to panic().
  55. 01e,03apr87,ecs  added copyright.
  56. 01d,02apr87,jlf  delinted.
  57. 01c,27feb87,dnw  change myTaskId() to vxMyTaskId().
  58. 01b,22dec86,dnw  added bcmp.
  59. 01a,28jul86,rdc  written.
  60. */
  61. /*
  62. DESCRIPTION
  63. This library provides routines that simulate or replace Unix kernel functions
  64. that are used in the network code.  This includes the spl...() processor
  65. level locking routines, wakeup() and sleep() (renamed ksleep() to avoid
  66. confusion with the C library routine called sleep()), perror() and panic(),
  67. and a checksum routine.
  68. */
  69. #include "vxWorks.h"
  70. #include "semLib.h"
  71. #include "sys/types.h"
  72. #include "net/mbuf.h"
  73. #include "taskLib.h"
  74. #include "netinet/in.h"
  75. #include "netinet/in_systm.h"
  76. #include "lstLib.h"
  77. #include "net/systm.h"
  78. #include "logLib.h"
  79. #include "intLib.h"
  80. #ifdef WV_INSTRUMENTATION
  81. #ifdef INCLUDE_WVNET
  82. #include "wvNetLib.h"
  83. #endif
  84. #endif
  85. /* local variables */
  86. #ifdef WV_INSTRUMENTATION
  87. #ifdef INCLUDE_WVNET
  88.     /* Set common fields of event identifiers for this module. */
  89. LOCAL UCHAR wvNetModuleId = WV_NET_UNIXLIB_MODULE; /* Value for unixLib.c */
  90. LOCAL UCHAR wvNetLocalFilter = WV_NET_NONE;     /* Available event filter */
  91. LOCAL ULONG wvNetEventId;       /* Event identifier: see wvNetLib.h */
  92. #endif    /* INCLUDE_WVNET */
  93. #endif
  94. /* global variables */
  95. BOOL   panicSuspend; /* TRUE = suspend task causing panic */
  96. #ifndef VIRTUAL_STACK
  97. int    splTid; /* owner of network processor level semaphore */
  98. SEM_ID splSemId; /* spl mutex semaphore id */
  99. #else
  100. #include "netinet/vsLib.h"
  101. #endif /* VIRTUAL_STACK */
  102. int mutexOptionsUnixLib = SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE;
  103. FUNCPTR _panicHook = NULL; /* panicHook for error recovery mechanism */
  104. /*******************************************************************************
  105. *
  106. * splSemInit - initialize the semaphore used by splnet, splimp, etc.
  107. *
  108. * This routine is called by netLibInit () to initialize the spl semaphore.
  109. *
  110. * NOMANUAL
  111. */
  112. void splSemInit ()
  113.     {
  114.     splSemId = semMCreate (mutexOptionsUnixLib);
  115.     }
  116. /******************************************************************************
  117. *
  118. * splnet - set network processor level
  119. *
  120. * splnet may be used to insure mutual exclusion among processes which
  121. * share common network data structures.  In UNIXland, this is done by
  122. * setting the processor interrupt level.  Here in VxWorksLand, however,
  123. * we use a simple semaphore mechanism.  splx should be called after
  124. * completion of the critical section.  We must check first to see if we're
  125. * already at network level.
  126. *
  127. * RETURNS: previous "processor level"
  128. */
  129. int splnet ()
  130.     {
  131.     if ((ULONG) taskIdCurrent == splTid)
  132. return (1);
  133.     semTake (splSemId, WAIT_FOREVER);
  134.     splTid = (ULONG) taskIdCurrent;
  135.     return (0);
  136.     }
  137. /******************************************************************************
  138. *
  139. * splnet2 - set network processor level _immediately_
  140. *
  141. * WARNING:  Calling this routine with a timeout that is not WAIT_FOREVR 
  142. *           is a violation of mutual exclusion and will cause problems in
  143. *           a running system.
  144. *           The caller must have very specific knowledge of the state of
  145. *           the networking system.
  146. *
  147. * RETURNS: previous "processor level"
  148. */
  149. int splnet2 (timeout)
  150.     int timeout; /* Number of ticks to wait spl semaphore */
  151.     {
  152.     if ((ULONG) taskIdCurrent == splTid)
  153.         return (1);
  154.     semTake (splSemId, timeout);
  155.     splTid = (ULONG) taskIdCurrent;
  156.     return (0);
  157.     }
  158. /*******************************************************************************
  159. *
  160. * splimp - set imp processor level
  161. *
  162. * This routine is indentical to splnet().
  163. * Currently, all network interlocking uses the same network semaphore.
  164. *
  165. * RETURNS: previous "processor level"
  166. */
  167. int splimp ()
  168.     {
  169.     if ((ULONG) taskIdCurrent == splTid)
  170. return (1);
  171.     semTake (splSemId, WAIT_FOREVER);
  172.     splTid = (ULONG) taskIdCurrent;
  173.     return (0);
  174.     }
  175. /*******************************************************************************
  176. *
  177. * splx - set processor level
  178. *
  179. * splx is used in UNIX to restore the processor level.
  180. * It is used in VxWorks in conjunction with splnet() and splimp() to provide
  181. * mutual exclusion of network data structures.  splx marks the end of the
  182. * critical section.
  183. */
  184. void splx (x)
  185.     int x; /* processor level to restore */
  186.     {
  187.     if (x == 0)
  188. {
  189. splTid = 0;
  190. semGive (splSemId);
  191. }
  192.     }
  193. /*******************************************************************************
  194. *
  195. * ksleep -  put a process to sleep
  196. *
  197. * In Unix, processes can sleep on any value (typically an address).
  198. * In VxWorks, we substitute a semaphore mechanism so sleep()
  199. * calls have to be changed to provide the address of a semaphore.
  200. *
  201. * Note: In Unix there are two "sleep" routines.  In the kernel, the sleep
  202. * routine causes a process to block until a wakeup is done on the same
  203. * value that sleep was called with.  This routine, and the wakeup routine
  204. * below, are replacements for that mechanism.  However, in the C library
  205. * there is another sleep() routine that will suspend a process for a
  206. * specified number of seconds.  Since VxWorks users porting an application
  207. * may have calls to the latter but not the former, there is potential for
  208. * vast confusion.  Thus this routine has been renamed "ksleep" ("kernel sleep")
  209. * and all calls to it in network code have been changed.
  210. */
  211. void ksleep (semId)
  212.     SEM_ID semId;
  213.     {
  214.     BOOL hadSplSem;
  215.     /* first see if we've got the network semaphore (splSemId);
  216.      * if so, give it, and then take it back when we are awakened.
  217.      */
  218.     hadSplSem = (splTid == (ULONG) taskIdCurrent);
  219.     if (hadSplSem)
  220. {
  221. splTid = 0;
  222. semGive (splSemId);
  223. }
  224.     semTake (semId, WAIT_FOREVER);
  225.     if (hadSplSem)
  226. {
  227. semTake (splSemId, WAIT_FOREVER);
  228. splTid = (ULONG) taskIdCurrent;
  229. }
  230.     }
  231. /*******************************************************************************
  232. *
  233. * wakeup - wakeup a sleeping process
  234. */
  235. void wakeup (semId)
  236.     SEM_ID semId;
  237.     {
  238.     semGive (semId);
  239.     }
  240. #ifdef unixLib_PORTABLE
  241. /*******************************************************************************
  242. *
  243. * _insque - insert node in list after specified node.
  244. *
  245. * Portable version of _insque ().
  246. */
  247. void _insque (pNode, pPrev)
  248.     NODE *pNode;
  249.     NODE *pPrev;
  250.     {
  251.     NODE *pNext;
  252.     pNext = pPrev->next;
  253.     pPrev->next = pNode;
  254.     pNext->previous = pNode;
  255.     pNode->next = pNext;
  256.     pNode->previous = pPrev;
  257.     }
  258. /*******************************************************************************
  259. *
  260. * _remque - remove specified node in list.
  261. *
  262. * Portable version of _remque ().
  263. */
  264. void _remque (pNode)
  265.     NODE *pNode;
  266.     {
  267.     pNode->previous->next = pNode->next;
  268.     pNode->next->previous = pNode->previous;
  269.     }
  270. #endif /* unixLib_PORTABLE */
  271. /*******************************************************************************
  272. *
  273. * panic - something is very wrong
  274. *
  275. * panic simply logs a message to the console prepended with "panic".
  276. * If the panic occurs at task level, the current task is suspended.
  277. */
  278. void panic (msg)
  279.     char *msg;
  280.     {
  281.     /* execute the panic hook if one exists */
  282.     if (_panicHook != NULL)
  283.         {
  284.         (*_panicHook) (msg); 
  285.         return; 
  286.         }
  287.         
  288.     logMsg ("panic: %sn", (int)msg, 0,0,0,0,0);
  289.     if (!intContext () && panicSuspend)
  290. taskSuspend (0);
  291.     }
  292. /*******************************************************************************
  293. *
  294. * _netMalloc - allocates network buffers
  295. *
  296. * This function allocates the relevant cluster and returns the 
  297. * the pointer to the memory allocated.
  298. * INTERNAL
  299. * The first 4 bytes of the cluster allocated hold a back pointer to the mBlk
  300. * The actual cluster size allocated is the user requested size + size of 
  301. * mBlk pointer to pointer.
  302. *
  303. * NOMANUAL
  304. *
  305. * RETURNS: char pointer /NULL 
  306. */
  307. char * _netMalloc
  308.     (
  309.     int bufSize, /* size of the buffer to get */
  310.     UCHAR type, /* type of mbuf to allocate */
  311.     int  canWait /* M_WAIT/M_DONTWAIT */
  312.     )
  313.     { 
  314.     FAST struct mbuf *  pMblk; 
  315.     FAST struct mbuf ** pPtrMblk; 
  316.     pMblk = netTupleGet (_pNetSysPool, (bufSize + sizeof(struct mbuf *)),
  317.                          canWait, type, TRUE);
  318.     if (pMblk != NULL) 
  319. pPtrMblk = mtod(pMblk, struct mbuf **); 
  320. *pPtrMblk = pMblk; 
  321. pMblk->m_data += sizeof(struct mbuf **); 
  322. return (mtod(pMblk, char *));
  323.     else 
  324. return (NULL); 
  325.     }
  326. /*******************************************************************************
  327. *
  328. * _netFree - frees network buffers
  329. *
  330. * This function allocates the relevant cluster and returns the 
  331. * the pointer to the memory allocated.
  332. * INTERNAL
  333. * The first 4 bytes of the cluster allocated hold a back pointer to the mBlk
  334. * The actual cluster size allocated is the user requested size + 4.
  335. * Since the mBlk will retain the type,m_free() will automatically free the 
  336. * relevant type
  337. *
  338. * NOMANUAL
  339. *
  340. * RETURNS: pointer/NULL 
  341. */
  342. void _netFree
  343.     (
  344.     char * pBuf /* pointer to buffer to free */  
  345.     ) 
  346.     {
  347.     if (pBuf != NULL)
  348. (void)m_free (*((struct mbuf **)(pBuf - sizeof(struct mbuf **))));
  349.     }
  350. /*******************************************************************************
  351. *
  352. * hashinit - initialize a hash table of a given size.
  353. *
  354. * This function initializes the hashtable of a given number of elements.
  355. * It returns a pointer to the hash mask. 
  356. * NOMANUAL
  357. *
  358. * RETURNS: pointer/NULL 
  359. */
  360. void * hashinit
  361.     (
  362.     int  elements, /* number of elements in the hash table */
  363.     int  type, /* type of entries PCB/IFADDR etc */
  364.     u_long * hashmask /* ptr to the hash mask */
  365.     )
  366.     {
  367.     long  hashsize;
  368.     int  ix;
  369.     LIST_HEAD(generic, generic) *hashtbl;
  370.     if (elements <= 0)
  371.         {
  372. #ifdef WV_INSTRUMENTATION
  373. #ifdef INCLUDE_WVNET    /* WV_NET_EMERGENCY event */
  374.         WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_EMERGENCY, 45, 1,
  375.                          WV_NETEVENT_HASHINIT_PANIC, type)
  376. #endif  /* INCLUDE_WVNET */
  377. #endif
  378.         panic("hashinit: bad elements");
  379.         }
  380.     
  381.     for (hashsize = 1; hashsize <= elements; hashsize <<= 1)
  382.         continue;
  383.     
  384.     hashsize >>= 1;
  385.     hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl));
  386.     for (ix = 0; ix < hashsize; ix++)
  387.         LIST_INIT(&hashtbl[ix]);
  388.     *hashmask = hashsize - 1;
  389.     return (hashtbl);
  390.     }