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

VxWorks

开发平台:

C/C++

  1. /* cplusCore.cpp - core C++ run-time support */
  2. /* Copyright 1995 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 02d,06nov01,sn   removed obsolete vec_new/vec_delete
  8. 02c,30mar01,sn   fixed to build with diab
  9. 02b,03mar98,sn   renamed new_handler to __new_handler to conform with the
  10.                  GNU new.cc implementation.
  11. 02a,16jan98,sn   remove new/delete (henceforth provided in 
  12.                  target/src/cplus/libgcc)
  13. 01d,19jun95,srh  rename op new/delete intf for g++.
  14. 01c,19jun95,srh  cleanup picky warnings from g++
  15. 01b,17jun95,srh  fixed declaration of VOIDFUNCPTR_ARGS
  16. 01a,19may95,srh  cobbled together from WindC++
  17. */
  18. /*
  19. DESCRIPTION
  20. TODO: Update description
  21. This library provides run-time support and shell utilities that support
  22. the development of VxWorks applications in C++.  The run-time support can
  23. be broken into three categories:
  24. .IP - 4
  25. Support for C++ new and delete operators.
  26. .IP -
  27. Support for arrays of C++ objects.
  28. .IP -
  29. Support for initialization and cleanup of static objects.
  30. .LP
  31. Shell utilities are provided for:
  32. .IP - 4
  33. Resolving overloaded C++ function names.
  34. .IP -
  35. Hiding C++ name mangling, with support for terse or complete
  36. name demangling.
  37. .IP -
  38. Manual or automatic invocation of static constructors and destructors.
  39. .LP
  40. The usage of cplusLib is more fully described in the
  41. .I "WindC++ Gateway User's Guide."
  42. */
  43. /* Includes */
  44. #include "vxWorks.h"
  45. #include "sys/types.h"
  46. #include "cplusLib.h"
  47. #include "hashLib.h"
  48. #include "semLib.h"
  49. #include "taskLib.h"
  50. #include "new"
  51. /* Defines */
  52. /* Typedefs */
  53. typedef void (* VOIDFUNCPTR_ARGS) (void *, int, ...);
  54. /* Globals */
  55. char __cplusCore_o;
  56. #if defined(__GNUG__)
  57. extern new_handler __new_handler;
  58. #else
  59. static void (*__new_handler)() = 0;
  60. #endif
  61. SEM_ID cplusNewHdlMutex;
  62. /* Locals */
  63. #if ! defined (__GNUG__)
  64. LOCAL ArrayStore_T  * pArrayStore = 0;
  65. #endif
  66. /* Forward declarations */
  67. /****************************************************************
  68. *
  69. * cplusNewHandlerExists - true if application-specific new-handler exists
  70. *
  71. * NOMANUAL
  72. *
  73. * RETURNS: TRUE if new-handler exists, otherwise FALSE.
  74. */
  75. BOOL cplusNewHandlerExists ()
  76.     {
  77.     semTake (cplusNewHdlMutex, WAIT_FOREVER);
  78.     BOOL rval = (__new_handler != 0) ? TRUE : FALSE;
  79.     semGive (cplusNewHdlMutex);
  80.     return rval;
  81.     }
  82. /****************************************************************
  83. *
  84. * cplusCallNewHandler - call the allocation exception handler (C++)
  85. *
  86. * This function provides a procedural-interface to the new-handler.  It
  87. * can be used by user-defined new operators to call the current
  88. * new-handler. This function is specific to VxWorks and may not be
  89. * available in other C++ environments.
  90. *
  91. * RETURNS: N/A
  92. */
  93. void cplusCallNewHandler ()
  94.     {
  95.     semTake (cplusNewHdlMutex, WAIT_FOREVER);
  96.     if (__new_handler != 0)
  97. {
  98. (*__new_handler) ();
  99. }
  100.     semGive (cplusNewHdlMutex);
  101.     }
  102. /*******************************************************************************
  103. *
  104. * cplusTerminate - default final resting place of a unhandled C++ exception
  105. *
  106. * An unhandled exception eventually results in a call to 'terminate',
  107. * which is set by the VxWorks startup code to call this function.
  108. * Ths default behaviour can be changed using set_terminate. This function
  109. * should never be called directly by user code. 
  110. * NOMANUAL
  111. *
  112. * RETURNS: No return
  113. */
  114. void cplusTerminate ()
  115. {
  116. cplusLogMsg ("Unhandled C++ exception resulted in call to terminaten",
  117.        0, 0, 0, 0, 0, 0);
  118.   taskSuspend (0);
  119. }
  120. /*******************************************************************************
  121. *
  122. * cplusArraysInit - intialize run-time support for arrays
  123. *
  124. *
  125. * This routine simply checks to see if the arrayStore is already initialized,
  126. * and if it isn't, constructs a new one.
  127. *
  128. * RETURNS: N/A
  129. *
  130. * NOMANUAL
  131. */
  132. #if defined (__GNUG__)
  133. void cplusArraysInit ()
  134.     {
  135.     }
  136. #else
  137. void cplusArraysInit ()
  138.     {
  139.     if (pArrayStore == 0)
  140. {
  141. pArrayStore = new ArrayStore_T ();
  142. }
  143.     }
  144. /*******************************************************************************
  145. *
  146. * arrHashFunc - array hashing function
  147. *
  148. * This function takes the address of the first element of the array,
  149. * throws away the rightmost 4 bits and returns this value, scaled to fit
  150. * the number of elements in the hash table.
  151. *
  152. * RETURNS:
  153. * Hash value h: 0 <= h < nElems
  154. *
  155. * NOMANUAL
  156. */
  157. static int arrHashFunc
  158.     (
  159.     int nElems,
  160.     HASH_NODE *pHashNode,
  161.     int
  162.     )
  163.     {
  164.     int hash = int ((((ArrayDesc_T *)(pHashNode)) -> pObject)) >> 4;
  165.     hash &= nElems-1;
  166.     return hash;
  167.     }
  168. /*******************************************************************************
  169. *
  170. * arrHashCmp - array hashing comparator
  171. *
  172. * This routine compares two array descriptors for identity.
  173. *
  174. * RETURNS:
  175. * TRUE if descriptors indicate the same array, otherwise FALSE
  176. *
  177. * NOMANUAL
  178. */
  179. static BOOL arrHashCmp
  180.     (
  181.     HASH_NODE * pMatchNode,
  182.     HASH_NODE * pHashNode,
  183.     int
  184.     )
  185.     {
  186.     return (((ArrayDesc_T *)(pMatchNode))->pObject
  187.     ==
  188.     ((ArrayDesc_T *)(pHashNode))->pObject);
  189.     }
  190. /*******************************************************************************
  191. * ArrayStore_T :: ArrayStore_T - initialize the ArrayStore
  192. *
  193. * This constructor creates a hash table in which to store the array
  194. * descriptors, and a mutex semaphore to guard access to the hash
  195. * table.
  196. *
  197. * RETURNS: N/A
  198. *
  199. * NOMANUAL
  200. */
  201. ArrayStore_T :: ArrayStore_T ()
  202.     {
  203.     hashId = hashTblCreate (8, // log2(size of hash table)
  204.     (FUNCPTR) arrHashCmp,
  205.     (FUNCPTR) arrHashFunc,
  206.     0);
  207.     mutexSem = semMCreate (SEM_Q_PRIORITY
  208.    | SEM_DELETE_SAFE
  209.    | SEM_INVERSION_SAFE);
  210.     }
  211. /******************************************************************************
  212. *
  213. * ArrayStore_T :: ~ArrayStore_T - decommission the ArrayStore
  214. *
  215. * This destructor should not ever be called. It detects the error condition
  216. * which arises if the arrayStore is deleted.
  217. *
  218. * RETURNS: N/A
  219. *
  220. * NOMANUAL
  221. */
  222. ArrayStore_T :: ~ArrayStore_T ()
  223.     {
  224.     cplusLogMsg ("run-time support for C++ arrays deletedn",
  225.  0, 0, 0, 0, 0, 0);
  226.     taskSuspend (0);
  227.     }
  228. /****************************************************************
  229. *
  230. * ArrayStore_T :: insert
  231. *
  232. * This function creates a new array descriptor and adds it to
  233. * the arrayStore. Problems are dealt with as for any failure of
  234. * a new operator. Memory for the array descriptor is allocated
  235. * by this function.
  236. *
  237. * RETURNS: N/A
  238. *
  239. * NOMANUAL
  240. */
  241. void ArrayStore_T :: insert
  242.     (
  243.     void * pObject,
  244.     int   nElems
  245.     )
  246.     {
  247.     ArrayDesc_T * pNode = new ArrayDesc_T (pObject, nElems);
  248.     semTake (mutexSem, WAIT_FOREVER);
  249.     // Cast the ArrayDesc_T pointer before storing in the hash table
  250.     if (hashTblPut (hashId, (HASH_NODE *)(pNode)) == ERROR)
  251. {
  252. cplusCallNewHandler ();
  253. }
  254.     semGive (mutexSem);
  255.     }
  256. /*****************************************************************
  257. *
  258. * ArrayStore_T :: fetch
  259. *
  260. * This function looks up a descriptor for the array specified by
  261. * <pObject>. When found, the descriptor is removed from the hash table
  262. * and deleted, then the number of elements is returned. Memory for the
  263. * array descriptor is reclaimed by this function.
  264. *
  265. * RETURNS: the number of elements in the specified array, if found,
  266. *          otherwise -1.
  267. *
  268. * NOMANUAL
  269. */
  270. int ArrayStore_T :: fetch
  271.     (
  272.     void * pObject
  273.     )
  274.     {
  275.     int rval;
  276.     HASH_NODE * pNode;
  277.     ArrayDesc_T node (pObject, 0);
  278.     semTake (mutexSem, WAIT_FOREVER);
  279.     if ((pNode = hashTblFind (hashId, (HASH_NODE *) (&node), 0)) == 0)
  280. {
  281. rval = -1;
  282. }
  283.     else
  284. {
  285. // Cast the fetched pointer back to ArrayDesc_T
  286. ArrayDesc_T * ad = (ArrayDesc_T *)(pNode);
  287. rval = ad->nElems;
  288. hashTblRemove (hashId, (HASH_NODE *) pNode);
  289. delete ad;
  290. }
  291.     semGive (mutexSem);
  292.     return rval;
  293.     }
  294. #endif // defined (__GNUG__)