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

VxWorks

开发平台:

C/C++

  1. /* comGuidLib.c - vxcom GUID library */
  2. /* Copyright (c) 2001 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01d,19nov01,nel  Add delay back into GUID creation routine.
  7. 01c,01nov01,nel  SPR#71383. Correct time adjustment algorithm.
  8. 01b,27jun01,dbs  fix compiler warnings
  9. 01a,21jun01,nel  created
  10. */
  11. /*
  12. DESCRIPTION
  13. A library for generated GUIDs as defined in the DCE spec. There is 
  14. a protection mechanism against generating GUIDs to quickly for the 
  15. timer granularity to cope with.
  16. */
  17. typedef struct _GUID
  18.     {
  19.     unsigned long timeLow;
  20.     unsigned short timeMid;
  21.     unsigned short timeHiAndVersion;
  22.     unsigned char clockSeqHiAndReserved;
  23.     unsigned char clockSeqLow;
  24.     unsigned char node[6];
  25.     } GUID;
  26. /*
  27.  * Various constants and masks used in uuid generation.
  28.  */
  29. #define UUID_C_VERSION  (1)
  30. #define CLOCK_SEQ_LOW_MASK (0xff)
  31. #define CLOCK_SEQ_HIGH_MASK (0x3f00)
  32. #define CLOCK_SEQ_HIGH_SHIFT_COUNT (8)
  33. #define CLOCK_SEQ_FIRST (1)
  34. #define CLOCK_SEQ_LAST (0x3fff) /* same as RAND_MASK */
  35. #define RAND_MASK (CLOCK_SEQ_LAST)
  36. /* 'adjustment' for backwards clocks */
  37. static int clockSeq = 0;
  38. /* Last time a UUID was generated or 0 if first time class is exectued. */
  39. static long unsigned long last = 0;
  40. /* Adjustment to cope with reduced granularity of the clock. */
  41. static int adjustment = 0;
  42. /* Used to store last uuid generated so that duplicates can be checked for. */
  43. static GUID lastGuid = { 0, };
  44. /*
  45.  * Create's a new clock sequence value. This is a randomnly gerenated field
  46.  * in the UUID which ensures that two UUIDs generated at the same time stand
  47.  * some chance of being unique.
  48.  */
  49. static void newClockSeq (void)
  50.     {
  51.     clockSeq = rand() & RAND_MASK;
  52.     clockSeq = (clockSeq + 1) & CLOCK_SEQ_LAST;
  53.     if (clockSeq == 0)
  54.         {
  55.         clockSeq++;
  56.         }
  57.     }
  58. static long unsigned long clockGet (void)
  59.     {
  60.     long unsigned long usec;
  61.     long unsigned long clockReg;
  62.     /* convert seconds to usecs */
  63.     usec = (long unsigned long)comSysTimeGet () * 1000000; 
  64.     if (last == 0)
  65. {
  66. newClockSeq();
  67. last = usec - 1;
  68. }
  69.     if (usec < last )
  70. {
  71. clockSeq = (clockSeq + 1) & 0x1FFF;
  72. adjustment = 0;
  73. }
  74.     else if (usec == last)
  75. {
  76. if (adjustment >= 999)
  77.     {
  78.     newClockSeq ();
  79.     adjustment = 0;
  80.     }
  81. else
  82.     adjustment++;
  83. }
  84.     else
  85. adjustment = 0;
  86.     last = usec;
  87.     clockReg = usec * 10;
  88.     clockReg += adjustment;
  89.     clockReg += 0x01B21DD213814000LL; /* Difference between DTSS UTC and Unix */
  90.            /* DTSS starts October 15, 1582. */
  91.     return clockReg;
  92.     }
  93. void comSysGuidCreate 
  94.     (
  95.     void * result /* Result that is mapped onto an */
  96.      /* IDL GUID structure by higher layers*/
  97.     )
  98.     {
  99.     do
  100.         {
  101.         long unsigned long timeNow = clockGet ();
  102.         ((GUID *)result)->timeLow = timeNow & 0xffffffff;
  103.         ((GUID *)result)->timeMid = (timeNow >> 32) & 0xffff;
  104.         ((GUID *)result)->timeHiAndVersion = ((timeNow >> 48) & 0xffff) | 
  105.                (UUID_C_VERSION << 12);
  106.         ((GUID *)result)->clockSeqLow = (short) (clockSeq & CLOCK_SEQ_LOW_MASK);
  107.         ((GUID *)result)->clockSeqHiAndReserved =
  108.                 ((short) ((clockSeq & CLOCK_SEQ_HIGH_MASK) >> 
  109.                     CLOCK_SEQ_HIGH_SHIFT_COUNT)) | 0x80;
  110.      comSysAddressGet ( ((GUID *)result)->node );
  111.         /**
  112.          * check to see if the last guid has been duplicated, if it has then
  113.          * wait a bit and try again. this should ensure that the next guid
  114.          * generated is unique.
  115.          */
  116.         if (memcmp (&lastGuid, result, sizeof (GUID)) != 0)
  117.             {
  118.             /* last GUID is different from current GUID so is correct */
  119.             memcpy (&lastGuid, result, sizeof (GUID));
  120.             return;
  121.             }
  122. taskDelay (1);
  123.         } while (1); /* loop until a vaild GUID is generated */
  124.     }