# 2.11BSD#431 - /usr/src/sys/sys/ingreslock.c

##### Functions

    ingres_open       X
    ingres_rma        X
    ingres_write      X

##### Variables

    Lockset           X
    Locksleep         X
    Locktab           X
    Locktabseg        X

##### Macros

    keycomp           X

       1: /*
       2:  * Rewritten for 2.11BSD. Feb 20 1995, Steven Schultz (sms@wlv.iipo.gtegsc.com)
       3:  *
       4:  * The lock table is allocated external to the kernel (in pdp/machdep2.c at
       5:  * kernel startup time) because 8 concurrent Ingres sessions would have cost
       6:  * over 500 bytes of D space.
       7:  */
       8:
       9: #include    "ingres.h"
      10: #if NINGRES > 0
      11:
      12: #include    "param.h"
      13: #include    <sys/file.h>
      14: #include    <sys/user.h>
      15: #include    <sys/proc.h>
      16: #include    <sys/uio.h>
      17: #include    <machine/seg.h>
      18: #include    <sys/ingreslock.h>
      19:
      20: /*
      21:  * Wait channels for locktable.  We need something which is even, unique and
      22:  * not mapped out to sleep on when waiting for a lock.
      23: */
      24:     int Locksleep[IL_NLOCKS];
      25:     segm    Locktabseg;
      26:     struct  Lockform *Locktab = (struct Lockform *)SEG5;
      27:
      28: /*
      29:  * array of number of locks which can be set for each lock.
      30:  * It looks tempting to make this an array of char or u_char.  DON'T.  The
      31:  * entries are used as wait channel addresses and must be 'even'.
      32: */
      33:     int Lockset[] =
      34:         {
      35:         IL_NLOCKS,
      36:         IL_PLOCKS,
      37:         IL_RLOCKS,
      38:         IL_DLOCKS
      39:         };
      40:
      41: #define keycomp(a,b)    bcmp(a,b,KEYSIZE)
      42:
      43: ingres_open(dev, flag, mode)
      44:     dev_t   dev;
      45:     int flag;
      46:     int mode;
      47:     {
      48:
      49:     if  ((flag & FWRITE) == 0)
      50:         return(EBADF);
      51:     if  (Locktabseg.se_addr == 0)
      52:         return(ENOMEM);
      53:     return(0);
      54:     }
      55:
      56: /*
      57:  *	ingres_write() : write driver
      58:  *		1. copy Lock request info to lockbuf
      59:  *		2. follow action in l_act
      60:  *		3. Error return conditions
      61:  *			-1: lockrequest fails(only on act=1)
      62:  *			-2: attempt to release a lock not set
      63:  *			    by calling program
      64:  *			-3: illegal action requested
      65:  *
      66:  *	Install the line "ingres_rma(p->p_pid)" in the routine
      67:  *	"exit" (in sys/kern_exit.c) after "p->p_stat = SZOMB".
      68: */
      69:
      70: ingres_write(dev, uio, flag)
      71:     dev_t   dev;
      72:     struct  uio *uio;
      73:     int flag;
      74: {
      75:     struct Lockreq  lockbuf;
      76:     register struct Lockreq *ll;
      77:     register int    i;
      78:     int error = 0, blockflag;
      79:
      80:     if  (uio->uio_resid != sizeof (struct ulock))
      81:         return(EINVAL);
      82:     error = uiomove(&lockbuf.lr_req, sizeof (struct ulock), uio);
      83:     if  (error)
      84:         return(error);
      85:     lockbuf.lr_pid = u.u_procp->p_pid;
      86:     ll = &lockbuf;
      87:     if  ((ll->lr_act < A_RLS1)
      88:            && ((ll->lr_type < T_CS) || (ll->lr_type > T_DB )
      89:            || (ll->lr_mod < M_EXCL) || (ll->lr_mod > M_SHARE )))
      90:         return(EINVAL);
      91:
      92: /*
      93:  * At this point we are in the high kernel and do not need to save seg5
      94:  * before changing it.  Making sure that 'normalseg5' is called before doing
      95:  * a sleep() or return() is sufficient.
      96:  *
      97:  * It is simpler to map the lock table once here rather than in each routine
      98:  * called below.
      99: */
     100:     ingres_maplock();
     101:
     102:     switch(ll->lr_act)
     103:     {
     104:       case A_RTN:
     105:                     /*
     106: 					 * attempt to set lock.
     107: 					 * error return if failure.
     108: 					 */
     109:         blockflag = FALSE;
     110:         for ( i = 0; i <= ll->lr_type; i++)
     111:             if (Lockset[i] == 0)
     112:                 blockflag = TRUE;
     113:         if (blockflag || ingres_unique(ll) >= 0)
     114:             error = -1;
     115:         else
     116:             ingres_enter(ll);
     117:         break;
     118:
     119:       case A_SLP:
     120:                 /* attempt to set lock.
     121: 				 * sleep on blocking address if failure.
     122: 				 */
     123:         do
     124:         {
     125:             do
     126:             {
     127:                 blockflag = TRUE;
     128:                 for ( i = 0; i <= ll->lr_type; i++)
     129:                     if (Lockset[i] == 0)
     130:                         {
     131:                         normalseg5();
     132:                         sleep(&Lockset[i],LOCKPRI);
     133:                         ingres_maplock();
     134:                         blockflag = FALSE;
     135:                         }
     136:             }
     137:             while (!blockflag);
     138:             if (( i = ingres_unique(ll)) >= 0 )
     139:                 {
     140:                 blockflag = FALSE;
     141:                 Locktab[i].l_wflag = W_ON;
     142:                 normalseg5();
     143:                 sleep(&Locksleep[i],LOCKPRI);
     144:                 ingres_maplock();
     145:                 }
     146:         }
     147:         while (!blockflag);
     148:         ingres_enter(ll);
     149:         break;
     150:
     151:       case A_RLS1:
     152:                 /* remove 1 lock */
     153:         if ((i = ingres_find(ll)) >= 0)
     154:             ingres_rm(i,ll->lr_pid);
     155:         else
     156:             error = -2;
     157:         break;
     158:
     159:       case A_RLSA:
     160:                 /* remove all locks for this process id*/
     161:         ingres_rma(ll->lr_pid); /* does a normalseg5() */
     162:         break;
     163:
     164:       case A_ABT:       /* abort all locks */
     165:         ingres_abt();
     166:         break;
     167:
     168:       default :
     169:         error = -3;
     170:         break;
     171:     }
     172:     normalseg5();
     173:     return(error);
     174: }
     175:
     176: /*
     177:  *	ingres_unique- check for match on key
     178:  *
     179:  *	return index of Locktab if match found
     180:  *	else return -1
     181:  */
     182:
     183: static
     184: ingres_unique(q)
     185: register struct Lockreq *q;
     186: {
     187:     register int    k;
     188:     register struct Lockform    *p = Locktab;
     189:
     190:     for (k = 0; k < IL_NLOCKS; k++, p++)
     191:         {
     192:         if  ((p->l_mod != M_EMTY)
     193:               && (keycomp(p->l_key,q->lr_key) == 0)
     194:               && (p->l_type == q->lr_type)
     195:               && ((p->l_mod == M_EXCL) || (q->lr_mod == M_EXCL)))
     196:             return(k);
     197:         }
     198:     return(-1);
     199: }
     200:
     201: static
     202: ingres_find(q)
     203: register struct Lockreq *q;
     204:     {
     205:     register int    k;
     206:     register struct Lockform    *p = Locktab;
     207:
     208:     for (k = 0; k < IL_NLOCKS; k++, p++)
     209:         {
     210:         if  ((p->l_mod != M_EMTY)
     211:               && (keycomp(p->l_key,q->lr_key) == 0)
     212:               && (p->l_type == q->lr_type)
     213:               && (p->l_pid == q->lr_pid))
     214:             return(k);
     215:         }
     216:     return(-1);
     217:     }
     218:
     219: /*
     220:  *	remove the lth Lock
     221:  *		if the correct user is requesting the move.
     222:  */
     223:
     224: static void
     225: ingres_rm(l,llpid)
     226:     int l, llpid;
     227:     {
     228:     register struct Lockform *a = &Locktab[l];
     229:     register int    k;
     230:
     231:     if  (a->l_pid == llpid && a->l_mod != M_EMTY)
     232:         {
     233:         a->l_mod = M_EMTY;
     234:         a->l_pid = 0;
     235:         if  (a->l_wflag == W_ON)
     236:             {
     237:             a->l_wflag = W_OFF;
     238:             wakeup(&Locksleep[l]);
     239:             }
     240:         for (k = 0; k <= a->l_type; k++)
     241:             {
     242:             Lockset[k]++;
     243:             if  (Lockset[k] == 1)
     244:                 wakeup(&Lockset[k]);
     245:             }
     246:         }
     247:     }
     248:
     249: /*
     250:  *	ingres_rma releases all locks for a given process id(pd).
     251: */
     252:
     253: ingres_rma(pd)
     254:     int pd;
     255:     {
     256:     register int    i;
     257:     register struct Lockform *p = Locktab;
     258: /*
     259:  * Have to map the lock table because we can be called from kern_exit.c
     260:  * when a process exits.
     261: */
     262:     ingres_maplock();
     263:
     264: /*
     265:  * Replicate the pid check here to avoid function calls.  If this process
     266:  * has no Ingres locks outstanding then we avoid IL_NLOCKS function calls
     267:  * and returns.
     268: */
     269:     for (i = 0; i < IL_NLOCKS; i++, p++)
     270:         {
     271:         if  (p->l_pid == pd && (p->l_mod != M_EMTY))
     272:             ingres_rm(i,pd);
     273:         }
     274:     normalseg5();
     275:     }
     276:
     277: /*
     278:  *	enter Lockbuf in locktable
     279:  *	return position in Locktable
     280:  *	error return of -1
     281:  */
     282:
     283: static
     284: ingres_enter(ll)
     285: struct Lockreq  *ll;
     286:     {
     287:     register int    k, l;
     288:     register struct Lockform    *p = Locktab;
     289:
     290:     for (k = 0; k < IL_NLOCKS; k++, p++)
     291:         {
     292:         if  (p->l_mod == M_EMTY)
     293:             {
     294:             p->l_pid = ll->lr_pid;
     295:             p->l_type = ll->lr_type;
     296:             p->l_mod = ll->lr_mod;
     297:             bcopy(ll->lr_key, p->l_key, KEYSIZE);
     298:             for (l = 0; l <= ll->lr_type; l++)
     299:                 Lockset[l]--;
     300:             return(k);
     301:             }
     302:         }
     303:     return (-1);
     304:     }
     305:
     306: /*
     307:  *	ingres_abt - abort all locks
     308:  */
     309:
     310: static void
     311: ingres_abt()
     312:     {
     313:     register int    k;
     314:
     315:     for (k = 0; k < IL_NLOCKS; k++)
     316:         wakeup( &Locktab[k] );
     317:     for (k = 0; k < 4; k++)
     318:         wakeup( &Lockset[k]);
     319:     bzero(Locktab, LOCKTABSIZE);
     320:     Lockset[0] = IL_NLOCKS;
     321:     Lockset[1] = IL_PLOCKS;
     322:     Lockset[2] = IL_RLOCKS;
     323:     Lockset[3] = IL_DLOCKS;
     324:     }
     325: #endif /* NINGRES > 0 */

#### Defined functions

ingres_abt defined in line 310; used 1 times

- in line 165

ingres_enter defined in line 283; used 2 times

- in line 116, 148

ingres_find defined in line 201; used 1 times

- in line 153

ingres_open defined in line 43; never used
ingres_rm defined in line 224; used 2 times

- in line 154, 272

ingres_rma defined in line 253; used 2 times

- in line 161
- in /usr/src/sys/sys/kern_exit.c line 109

ingres_unique defined in line 183; used 2 times

- in line 113, 138

ingres_write defined in line 70; never used

#### Defined variables

Lockset defined in line 33; used 12 times

- in line 111, 129-132(2), 242-244(3), 299, 318-323(5)

Locksleep defined in line 24; used 2 times

- in line 143, 238

Locktab defined in line 26; used 8 times

- in line 141, 188, 206, 228, 257, 288, 316-319(2)

Locktabseg defined in line 25; used 1 times

- in line 51

#### Defined macros

keycomp defined in line 41; used 2 times

- in line 193, 211

Last modified: 1995-02-21 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 915 |