ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 一段ORACLE内核C程序代码(续)

一段ORACLE内核C程序代码(续)

原创 Linux操作系统 作者:zhouly1861 时间:2009-01-12 14:02:45 0 删除 编辑

                Extract from ksl.c
                ==================
/*
** Get the latch specified by "id", on behalf  of  the  current
** session.  If "wait" is  FALSE,  return  immediately  if  the
** latch is in use; if TRUE, keep trying and  return  when  the
** latch has been granted.  Return TRUE  if  and  only  if  the
** latch was granted.  Raise an error if this is cleanup,  wait
** is TRUE, and the latch is busy.  This procedure  checks  for
** errors in latch sequence (based on level), and records  what
** latches are held so they can be freed if needed.
*/
                !!!*** C 01 ***!!!
word         kslget(l, wait)                                  /* get a latch */
reg0 ksllt  *l;                                     /* latch we are latching */
     word    wait;                          /* wait for latch or just return */
{
                !!!*** C 02 ***!!!
  reg1 kslla   *state;                                        /* latch state */
  reg2 word     level;                                     /* latching level */
  /* initialize */
                !!!*** C 03 ***!!!
  state = ksuglk(ksugcp());                    /* get process latching state */
  level = l->kslltlvl;                                 /* get level of latch */
#ifdef KSLDEBUG
  /* if currently hold a fast latch, cannot get another latch */
                !!!*** C 04 ***!!!
  if (state->ksllalaq)
    ksesic2(OERI(503), ksenrg(state->ksllalaq),
            ksesrgl((text *)kslldt[state->ksllalaq->kslltnum].kslldnam));
#endif
  /* Enforce latch hirearchy to prevent deadlocks.
   * Check if a latch is already held at this level or any higher level.
   */
                !!!*** C 05 ***!!!
  if (bit(state->ksllalow, levelbits[level]))
  {
                !!!*** C 06 ***!!!
    if (!wait)
    {
                !!!*** C 07 ***!!!
      if (!state->ksllalat[level])          /* no latch gotten at this level */
        ;                                    /* allow nowait get to proceded */
      /* allow one duplicate get at a level if it is gotten nowait */
      else if (state->ksllalat[level] != l && !state->ksllalat[KSLLMXLV+1])
        level = KSLLMXLV+1;     /* use the slot that is one past the highest */
      else                            /* never signal conflict on nowait get */
        return FALSE;
    }
    else
      ksesic4(
        OERI(504),               /* kslget: failure to follow lock hierarchy */
        ksenrg(l), ksenrg(state->ksllalow),
        ksenrg(level), ksesrgl((text *)kslldt[l->kslltnum].kslldnam));
  }
  /* set "we are waiting for the latch" and go try to get it */
  state->ksllalaq = l;
  /* Do a fast try to get the latch */
                !!!*** C 08 ***!!!
  if (sclgtf(&l->kslltlat))           /* do the test and set (or equivalent) */
  {
    /* Got the latch on first try */
    bis(state->ksllalow, 1 << level);    /* set level bit for level checking */
    state->ksllalat[level] = l;       /* indicate latch gotten at this level */
    l->kslltefd = kgetfd(ksmgpga);   /* error frame. depth for error recovery */
    /* Note that the number of latch gets is used during cleanup (it is not
     *  just for statistics).  So don't delete this code.
     */
    if (wait)
      l->kslltwgt++;                                       /* bump wait gets */
    else
      l->kslltngt++;                                     /* bump nowait gets */
    KSLDBG(state->ksllalaq = (ksllt *)0;)
    /* check if latch debugging is turned on */
    if (ksldbg)
    {
      /* set trace info if appropriate */
      kslsgtr(l, kslcmt);
      /* unprotect the latch's recovery structure if necessary */
      kslprrc(l, TRUE);
    }
    return TRUE;                                           /* return success */
  }
  else if (!wait)     /* if failed to get the latch and not supposed to wait */
  {
    /* Bump nowait attempts. This increment is not protected by the latch,
     * so it may be lost or garbled if several processes do this at the same
     * time.
     */
    l->kslltnfa++;                                        /* nowait failures */
    state->ksllalaq = (ksllt *)0;            /* not trying to get it anymore */
    return FALSE;
  }
  /* Someone else has the latch, we must wait for it.  Call kslges indirectly
   * so the compiler will not inline the routine (this causes many registers
   * to be saved unnecessarily).
   */  
                !!!*** C 09 ***!!!
  return (*kslger)(l, FALSE);
}
/* remove myself from list of waiter processes on a latch. */
STATICF void kslwrmv(state)
reg0 kslla *state;
{
  reg1 kslla  *wait_proc;
  reg2 kslla **proc_link;
  /* walk list of processes waiting for this latch */
                !!!*** C 10 ***!!!
  for (wait_proc = state->ksllawtr->kslltwkp,
       proc_link = &state->ksllawtr->kslltwkp;
       wait_proc;
       proc_link = &wait_proc->ksllanxw, wait_proc = *proc_link)
                !!!*** C 11 ***!!!
    if (wait_proc == state)                 /* if waiter is me */
    {
      *proc_link = state->ksllanxw;                  /* pop myself from list */
      break;
    }
  /* Note that if I was previously killed while linking or unlinking myself
   * from a wait list, I might never have made it on the list, but I would
   * still have my state set as if I did.  We always link on the the waiter
   * list last when adding to the wait list, and unlink first when removing
   * from the wait list.  Therefore I need to clear my state whether I am on
   * the list or not to cleanup from process death.
   */
  state->ksllanxw = (kslla *)0;                            /* no next waiter */
  state->ksllawtr = (ksllt *)0;           /* not on wait list for this latch */
}
/* Second part of kslget.   We failed to get  the latch on the  first try so
* now we have to wait for it.
*/
word  kslges(l, from_macro)
reg0 ksllt   *l;                                    /* latch we are latching */
eword from_macro;                        /* true if called from kslatm macro */
{
  ub4    i;                                                  /* miss counter */
  reg1 kslla   *state;                                        /* latch state */
  reg2 word     level;                                     /* latching level */
  reg3 eword    max_backoff = kslmex;        /* Let's initialize this, okay? */
       eword    other_latch = FALSE;
  /* initialize */
  state = ksuglk(ksugcp());                    /* get process latching state */
  level = l->kslltlvl;                                 /* get level of latch */
  /* Don't sleep too long if currently holding a latch since this will tend to
   * backup the people waiting for me.  This does not apply if the latch is
   * an allocated child latch since there are lots of those.
   */
  if (state->ksllalow)                       /* if currently holding a latch */
  {
    for (i = 0; i <= level; i++)             /* for all latches I am holding */
      if (state->ksllalat[i] &&
          !state->ksllalat[i]->kslltchn)       /* if holding non-child latch */
      {
        max_backoff = kslmsl;            /* set max backoff to smaller value */
        other_latch = TRUE;          /* remember we're holding another latch */
        break;
      }
  }
  /* keep trying to get the latch until we succeed */
  for (i = 0; ; i++)
  {
    serc   se;
    /* set "we are waiting for the latch" and go get it */
    state->ksllalaq = l;
    /* try to get the latch again */
    if (sclgts(&se, &l->kslltlat,                        /* the latch to get */
               ksugpi(ksugcp()),                /* the OSD process structure */
               &state->ksllalaq,       /* pointer to latch trying to acquire */
               ksuicl()))                        /* am I the cleanup process */
    {
      l->kslltwgt++;                             /* bump wait gets statistic */
      l->kslltwff++;                  /* bump failed first attempt statistic */
      l->kslltwsl += i;                        /* increment sleeps statistic */
      if (state->ksllalow) l->kslltwth++;  /* increment sleeps holding latch */
      /* increment histogram of wait times */
      if (i >= KSLHSTMAX)
        l->ksllthst[KSLHSTMAX-1]++;
      else l->ksllthst[i]++;     
      if (!from_macro)       /* don't set these if called by fast path macro */
      {
        bis(state->ksllalow, 1 << level);/* set level bit for level checking */
        state->ksllalat[level] = l;   /* indicate latch gotten at this level */

        KSLDBG(state->ksllalaq = (ksllt *)0;)
      }
      l->kslltefd = kgetfd(ksmgpga); /* error frame. depth for error recovery */
      /* check if latch debugging is turned on */
      if (ksldbg)
      {
        /* set trace info if appropriate */
        kslsgtr(l, kslcmt);

        /* unprotect the latch's recovery structure if necessary */
        kslprrc(l, TRUE);
      }
      return TRUE;
    }
    else
    {
      /* We did not get the latch, someone else must have it.  We must wait */
      state->ksllalaq = (ksllt *)0;       /* we are not trying to get it now */
      if (SERC_ERROR(se))           /* if something went wrong, signal error */
      {
        (*ksloet)();                                     /* Dump useful info */
        DISCARD ksecrs(&se);                            /* record error code */
        ksesic0(OERI(506));
      }
      if (i == 5 && !ksuicl()) /* if waited for a few hundreth's of a second */
        ksupsx();           /* post cleanup in case dead process holds latch */
      /* if should use post waiters option to latching */
                !!!*** C 12 ***!!!
      if (   kslpwt                                    /* waiting is enabled */
          && l != kslwlst           /* not waiting for the waiter list latch */
          && !from_macro         /* not from macro, macros don't call kslfre */
          && (i == 0 ||                           /* first time through loop */
              !state->ksllawtr)    /* someone woke me but I didn't get latch */
          && !state->ksllalat[kslwlst->kslltlvl]    /* no out of order latch */
          && (kslpwt > 1 ||               /* waiting enabled for all latches */
              kslldt[l->kslltnum].kslldlng))       /* this is a 'long' latch */
      {
        /* Add myself to the head of the waiter list. */
        KSLBEGIN(kslwlst)                     /* get latch waiter list latch */
          /* If I am still on waiter list of a latch that I am holding I need
           * to get off that list before going on another waiter list.  Note
           * that I don't normally take myself off a waiter list until I free
           * the latch to avoid adding extra code path under the latch that
           * people are waiting for.  This is why I could be on a waiter list
           * while I am holding the latch.
           */
          if (state->ksllawtr)              /* if on waiter list for a latch */
            kslwrmv(state);                      /* take myself off the list */
          state->ksllawtr = l;      /* latch whose waiter list I am going on */
          /* give preference to waiters that are holding another latch */
          if (l->kslltwkp                 /* if someone already on wait list */
              && !other_latch)               /* and I am not holding a latch */
          {
            /* put myself in second slot of wait list in case the person in
             * the first slot is holding a latch.  This gives him precedence.
             */
            /* people after first guy are now after me */
            state->ksllanxw = l->kslltwkp->ksllanxw;
            l->kslltwkp->ksllanxw = state;           /* I am after first guy */
          }
          else
          {
            /* put myself at the head of the waiter list */
            state->ksllanxw = l->kslltwkp;     /* head of list goes after me */
            l->kslltwkp = state;                     /* I go at head of list */
          }
        KSLEND                                  /* remember I am on the list */
      }
      state->ksllawat = l;                   /* set latch we are waiting for */
      /* do exponential backoff */
      kslewt3(i, max_backoff, (state->ksllawtr ? TRUE : FALSE),
              ksllfe, l, l->kslltnum, i);
      state->ksllawat = (ksllt *)0;        /* clear latch we are waiting for */
      ksucfi();  /* Check for any interrupts which are fatal to the instance */
      ksecss(&se);                                        /* check for error */
      if (i > 7 && ksuicl())               /* if PMON and waited long enough */
      {
        /* PMON has not been able to get the latch.  The latch might be held
         * by a dead process so search for dead processes, and free their
         * latches.  When freeing dead processes latches, PMON must only free
         * latches that have a higher level than the highest level latch he
         * is currently holding since freeing a latch can cause another
         * latch to be gotten which could lead to a conflict with the latches
         * PMON already holds.
         */
        DISCARD ksuxfl();                      /* free dead process' latches */
                !!!*** C 13 ***!!!
        if (i == 200)                           /* if waited for a long time */
        {
          ksupr *pr = kslown(l);             /* process that holds the latch */
          ksdwrf("PMON unable to acquire latch %lx %s\n", (unsigned long)l,
                 (char *)kslldt[l->kslltnum].kslldnam);
          if (pr)
            ksdwrf("  possible holder pid = %d spid=%.*s\n", (int)ksuprp(pr),
                   (int)ksugpri(pr)->ksuospdl, (char *)ksugpri(pr)->ksuospid);
          ksdddt();                                      /* write time stamp */
          ksdfls();                                       /* flush dump file */
          ksdwra("PMON failed to acquire latch, see PMON dump");
        }
      }
    }
  }
}
                oratypes.h
                ==========
/* /v71/d2/713/oracore/public/sx.h */
/*
ORACLE, Copyright (c) 1982, 1983, 1986, 1990 ORACLE Corporation
ORACLE Utilities, Copyright (c) 1981, 1982, 1983, 1986, 1990, 1991 ORACLE Corp
Restricted Rights
This program is an unpublished work under the Copyright Act of the
United States and is subject to the terms and conditions stated in
your  license  agreement  with  ORACORP  including  retrictions on
use, duplication, and disclosure.
Certain uncopyrighted ideas and concepts are also contained herein.
These are trade secrets of ORACORP and cannot be  used  except  in
accordance with the written permission of ORACLE Corporation.
*/
/* $Header: sx.h 7.18 94/04/05 18:34:34 tswang Osd $ */
#ifndef ORASTDDEF
# include
# define ORASTDDEF
#endif
#ifndef ORALIMITS
# include
# define ORALIMITS
#endif
#ifndef  SX_ORACLE
#define  SX_ORACLE
#define  SX
#define  ORATYPE
#ifndef TRUE
# define TRUE  1
# define FALSE 0
#endif
#ifdef lint
# ifndef mips
#  define signed
# endif
#endif
#ifdef ENCORE_88K
# ifndef signed
#  define signed
# endif
#endif
#ifdef SYSV_386
# ifndef signed
#  define signed
# endif
#endif
#ifndef lint
typedef          int eword;                 
typedef unsigned int uword;                 
typedef   signed int sword;                 
#else
#define eword int
#define uword unsigned int
#define sword signed int
#endif
#define  EWORDMAXVAL  ((eword) INT_MAX)
#define  EWORDMINVAL  ((eword)       0)
#define  UWORDMAXVAL  ((uword)UINT_MAX)
#define  UWORDMINVAL  ((uword)       0)
#define  SWORDMAXVAL  ((sword) INT_MAX)
#define  SWORDMINVAL  ((sword) INT_MIN)
#define  MINEWORDMAXVAL  ((eword)  32767)
#define  MAXEWORDMINVAL  ((eword)      0)
#define  MINUWORDMAXVAL  ((uword)  65535)
#define  MAXUWORDMINVAL  ((uword)      0)
#define  MINSWORDMAXVAL  ((sword)  32767)
#define  MAXSWORDMINVAL  ((sword) -32767)
#ifndef lint
# ifdef mips
typedef   signed char  eb1;
# else
typedef          char  eb1;                 
# endif
typedef unsigned char  ub1;                 
typedef   signed char  sb1;                 
#else
#define eb1 char
#define ub1 unsigned char
#define sb1 signed char
#endif
#define EB1MAXVAL ((eb1)SCHAR_MAX)
#define EB1MINVAL ((eb1)        0)
#if defined(mips)                    
# ifndef lint
#  define UB1MAXVAL (UCHAR_MAX)
# endif
#endif
#ifndef UB1MAXVAL
# ifdef SCO_UNIX
# define UB1MAXVAL (UCHAR_MAX)
# else
# define UB1MAXVAL ((ub1)UCHAR_MAX)
# endif
#endif
#define UB1MINVAL ((ub1)        0)
#define SB1MAXVAL ((sb1)SCHAR_MAX)
#define SB1MINVAL ((sb1)SCHAR_MIN)
#define MINEB1MAXVAL ((eb1)  127)
#define MAXEB1MINVAL ((eb1)    0)
#define MINUB1MAXVAL ((ub1)  255)
#define MAXUB1MINVAL ((ub1)    0)
#define MINSB1MAXVAL ((sb1)  127)
#define MAXSB1MINVAL ((sb1) -127)
#define UB1BITS          CHAR_BIT
#define UB1MASK              0xff
typedef  unsigned char text;
#ifndef lint
typedef          short    eb2;              
typedef unsigned short    ub2;              
typedef   signed short    sb2;              
#else
#define eb2  short
#define ub2  unsigned short
#define sb2  signed short
#endif
#define EB2MAXVAL ((eb2) SHRT_MAX)
#define EB2MINVAL ((eb2)        0)
#define UB2MAXVAL ((ub2)USHRT_MAX)
#define UB2MINVAL ((ub2)        0)
#define SB2MAXVAL ((sb2) SHRT_MAX)
#define SB2MINVAL ((sb2) SHRT_MIN)
#define MINEB2MAXVAL ((eb2) 32767)
#define MAXEB2MINVAL ((eb2)     0)
#define MINUB2MAXVAL ((ub2) 65535)
#define MAXUB2MINVAL ((ub2)     0)
#define MINSB2MAXVAL ((sb2) 32767)
#define MAXSB2MINVAL ((sb2)-32767)
#ifndef lint
typedef          long  eb4;                 
typedef unsigned long  ub4;                 
typedef   signed long  sb4;                 
#else
#define eb4 long
#define ub4 unsigned long
#define sb4 signed long
#endif
#define EB4MAXVAL ((eb4) LONG_MAX)
#define EB4MINVAL ((eb4)        0)
#define UB4MAXVAL ((ub4)ULONG_MAX)
#define UB4MINVAL ((ub4)        0)
#define SB4MAXVAL ((sb4) LONG_MAX)
#define SB4MINVAL ((sb4) LONG_MIN)
#define MINEB4MAXVAL ((eb4) 2147483647)
#define MAXEB4MINVAL ((eb4)          0)
#define MINUB4MAXVAL ((ub4) 4294967295)
#define MAXUB4MINVAL ((ub4)          0)
#define MINSB4MAXVAL ((sb4) 2147483647)
#define MAXSB4MINVAL ((sb4)-2147483647)
#ifndef lint
typedef unsigned long  ubig_ora;            
typedef   signed long  sbig_ora;            
#else
#define ubig_ora unsigned long
#define sbig_ora signed long
#endif
#define UBIG_ORAMAXVAL ((ubig_ora)ULONG_MAX)
#define UBIG_ORAMINVAL ((ubig_ora)        0)
#define SBIG_ORAMAXVAL ((sbig_ora) LONG_MAX)
#define SBIG_ORAMINVAL ((sbig_ora) LONG_MIN)
#define MINUBIG_ORAMAXVAL ((ubig_ora) 4294967295)
#define MAXUBIG_ORAMINVAL ((ubig_ora)          0)
#define MINSBIG_ORAMAXVAL ((sbig_ora) 2147483647)
#define MAXSBIG_ORAMINVAL ((sbig_ora)-2147483647)
#undef CONST
#ifdef _olint
# define CONST const
#else
#if defined(PMAX) && defined(__STDC__)
#   define CONST const
#else
# ifdef M88OPEN
#  define CONST const
# else
#  ifdef SEQ_PSX_ANSI
#   ifdef __STDC__
#    define CONST const
#   else
#    define CONST
#   endif
#  else
#   define CONST
#  endif
# endif
#endif
#endif
#ifdef lint
# define dvoid void
#else
# ifdef UTS2
#  define dvoid char
# else
#  define dvoid void
# endif
#endif
typedef void (*lgenfp_t)(/*_ void _*/);
#include
#define boolean int
#ifdef sparc
# define SIZE_TMAXVAL SB4MAXVAL               
#else
# define SIZE_TMAXVAL UB4MAXVAL             
#endif
#define MINSIZE_TMAXVAL (size_t)65535
#endif

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/8797129/viewspace-536424/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2008-08-03

  • 博文量
    53
  • 访问量
    107049