page_op.c
上传用户:dgyhgb
上传日期:2007-01-07
资源大小:676k
文件大小:8k
源码类别:

SQL Server

开发平台:

Unix_Linux

  1. /*
  2.  *  page_op.c  - Operations with external storage pages (transaction)
  3.  *               Kernel of GNU SQL-server
  4.  *
  5.  *  This file is a part of GNU SQL Server
  6.  *
  7.  *  Copyright (c) 1996, 1997, Free Software Foundation, Inc
  8.  *  Developed at the Institute of System Programming
  9.  *  This file is written by  Vera Ponomarenko
  10.  *
  11.  *  This program is free software; you can redistribute it and/or modify
  12.  *  it under the terms of the GNU General Public License as published by
  13.  *  the Free Software Foundation; either version 2 of the License, or
  14.  *  (at your option) any later version.
  15.  *
  16.  *  This program is distributed in the hope that it will be useful,
  17.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  *  GNU General Public License for more details.
  20.  *
  21.  *  You should have received a copy of the GNU General Public License
  22.  *  along with this program; if not, write to the Free Software
  23.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  24.  *
  25.  *  Contacts:   gss@ispras.ru
  26.  *
  27.  */
  28. /* $Id: page_op.c,v 1.245 1997/03/31 03:46:38 kml Exp $ */
  29. #include "setup_os.h"
  30. #include <sys/types.h>
  31. #include <sys/ipc.h>
  32. #include <sys/msg.h>
  33. #include <sys/shm.h>
  34. #include <errno.h>
  35. #ifdef HAVE_UNISTD_H
  36. #include <unistd.h>
  37. #endif
  38. #include <assert.h>
  39. #include "xmem.h"
  40. #include "destrn.h"
  41. #include "strml.h"
  42. #include "fdcltrn.h"
  43. extern u2_t trnum;
  44. extern COST cost;
  45. extern struct ADBL admj;
  46. extern struct ADBL adlj;
  47. extern struct ADREC blmj;
  48. extern struct ADREC bllj;
  49. extern i4_t msqidb, msqidm, msqidl;
  50. extern i4_t N_AT_SEG;
  51. extern char *bufmj;
  52. extern char *pbuflj;
  53. extern char *pbufmj;
  54. #define COOKMSG(mcode,ptr)  {
  55.   sbuf.mtype = mcode;
  56.   ptr = sbuf.mtext;
  57.   BUFPACK(trnum, ptr);
  58.   BUFPACK(sn, ptr);
  59.   BUFPACK(pn, ptr);
  60. }
  61. char *
  62. getpg(struct A *ppage, u2_t sn, u2_t pn, i4_t type)
  63. {
  64.   struct msg_buf sbuf, rbuf;
  65.   char *p;
  66.   key_t keyseg;
  67.   i4_t shmid;
  68.   char *shm;
  69.   COOKMSG(LOCKGET,p);
  70.   *p = (type == 'x'? STRONG : WEAK );
  71.   __MSGSND(msqidb, &sbuf, 3 * size2b + 1, 0,"TRN.msgsnd: LOCKGET to BUF");
  72.   __MSGRCV(msqidb, &rbuf, sizeof (key_t), trnum, 0,
  73.            "TRN.msgrcv: LOCKGET from BUF");
  74.   TUPACK(rbuf.mtext, keyseg);
  75.   if (keyseg == BACKUP)
  76.     return (NULL);
  77.   if (keyseg == NO_SUCH_SEG)
  78.     {
  79.       fprintf (stderr, "TRN.getpg: No such segment seg_num = %dn", sn);
  80.       /*      return (NULL);*/
  81.       exit (0);
  82.     }
  83.   if ((shmid = shmget (keyseg, BD_PAGESIZE, DEFAULT_ACCESS_RIGHTS)) < 0)
  84.     {
  85.       perror ("TRN.shmget");
  86.       exit (1);
  87.     }
  88.   if ((shm = (char *) shmat (shmid, NULL, 0)) == (char *) -1)
  89.     {
  90.       printf ("TR.getpg: shmid=%d,sn=%d,pn=%d,errno=%dn",
  91.               shmid, sn, pn, errno);
  92.       perror ("TRN.shmat");
  93.       exit (1);
  94.     }
  95.   N_AT_SEG++;
  96.   ppage->p_shm = shm;
  97.   ppage->p_sn = sn;
  98.   ppage->p_pn = pn;
  99.   cost += 1;
  100.   return (shm);
  101. }
  102. char *
  103. getwl (struct A *ppage, u2_t sn, u2_t pn)
  104. {
  105.   struct msg_buf sbuf;
  106.   char *p;
  107.   i4_t shmid;
  108.   char *shm;
  109.   COOKMSG(GETPAGE,p);
  110.   __MSGSND(msqidb, &sbuf, 3 * size2b, 0,
  111.            "TRN.msgsnd: GETPAGE to BUF");
  112.   __MSGRCV(msqidb, &sbuf, sizeof (key_t), trnum, 0,
  113.            "TRN.msgrcv: GETPAGE from BUF");
  114.   if ((shmid = shmget (*(key_t *) sbuf.mtext,
  115.                        BD_PAGESIZE, DEFAULT_ACCESS_RIGHTS)) < 0)
  116.     {
  117.       perror ("TRN.shmget");
  118.       exit (1);
  119.     }
  120.   if ((shm = (char *) shmat (shmid, NULL, 0)) == (char *) -1)
  121.     {
  122.       printf ("TR.getwl: shmid=%d,sn=%d,pn=%d,errno=%dn", shmid, sn, pn, errno);
  123.       perror ("TRN.shmat");
  124.       exit (1);
  125.     }
  126.   N_AT_SEG++;
  127.   ppage->p_shm = shm;
  128.   ppage->p_sn = sn;
  129.   ppage->p_pn = pn;
  130.   cost += 1;
  131.   return (shm);
  132. }
  133. char *
  134. getnew (struct A *ppage, u2_t sn, u2_t pn)
  135. {
  136.   struct msg_buf sbuf;
  137.   i4_t shmid;
  138.   char *shm, *p;
  139.   COOKMSG(NEWGET,p);
  140.   __MSGSND(msqidb, &sbuf, 3 * size2b, 0,"TRN.msgsnd: NEWGET to BUF");
  141.   __MSGRCV(msqidb, &sbuf, sizeof (key_t), trnum, 0,
  142.            "TRN.msgrcv: NEWGET from BUF");
  143.   if ((shmid = shmget (*(key_t *) sbuf.mtext,
  144.                        BD_PAGESIZE, DEFAULT_ACCESS_RIGHTS)) < 0)
  145.     {
  146.       perror ("TRN.shmget");
  147.       exit (1);
  148.     }
  149.   if ((shm = (char *) shmat (shmid, NULL, 0)) == (char *) -1)
  150.     {
  151.       perror ("TRN.shmat");
  152.       exit (1);
  153.     }
  154.   N_AT_SEG++;
  155.   ppage->p_shm = shm;
  156.   ppage->p_sn = sn;
  157.   ppage->p_pn = pn;
  158.   cost += 1;
  159.   return (shm);
  160. }
  161. void
  162. putpg (struct A *ppage, i4_t type)
  163. {
  164.   struct msg_buf sbuf;
  165.   u2_t sn;
  166.   sn = ppage->p_sn;
  167.   if (sn == NRSNUM)
  168.     {
  169.       putwul (ppage, type);
  170.       return;
  171.     }
  172.   sbuf.mtype = PUTUNL;
  173.   put_page (ppage, type, &sbuf);
  174.   cost += 1;
  175. }
  176. void
  177. put_page (struct A *ppage, char type, struct msg_buf *sbuf)
  178. {
  179.   char *asp, *p;
  180.   u2_t sn, pn;
  181.   asp = ppage->p_shm;
  182.   sn = ppage->p_sn;
  183.   pn = ppage->p_pn;
  184.   p = sbuf->mtext;
  185.   BUFPACK (trnum, p);
  186.   BUFPACK (sn, p);
  187.   BUFPACK (pn, p);
  188.   if (type == 'm')
  189.     {
  190.       if (sn != NRSNUM)
  191. {
  192.   BUFPACK(admj, p);
  193.   ((struct p_head *) asp)->csum = CCS (asp);
  194. }
  195.       else
  196. {
  197.   bzero(p,size4b);
  198.   p += size4b;
  199. }
  200.       *p = (char) PRMOD;
  201.     }
  202.   else
  203.     {
  204.       bzero(p,size4b);
  205.       p += size4b;
  206.       *p = (char) PRNMOD;
  207.     }
  208.   __MSGSND(msqidb, sbuf, 5 * size2b + 1, 0,"TRN.msgsnd: PUTPAGE to BUF");
  209.   __MSGRCV(msqidb, sbuf, sizeof (i4_t), trnum, 0,
  210.            "TRN.msgrcv: PUTPAGE from BUF");
  211.   shmdt (asp);
  212.   N_AT_SEG--;
  213. }
  214. void
  215. putwul (struct A *ppage, i4_t type)
  216. {
  217.   struct msg_buf sbuf;
  218.   sbuf.mtype = PUTPAGE;
  219.   put_page (ppage, type, &sbuf);
  220.   cost += 1;
  221. }
  222. #define N_unlock (SZMSGBUF-3*size2b)/size2b
  223. void
  224. BUF_unlock (u2_t sn, u2_t lnum, u2_t * mpn)
  225. {
  226.   struct msg_buf sbuf,rbuf;
  227.   u2_t *p;
  228.   u2_t i = 0;
  229.   u2_t n = N_unlock, count = 0;
  230.   if (lnum == 0)
  231.     return;
  232.   sbuf.mtype = UNLKPG;
  233.   p = (u2_t *) sbuf.mtext;
  234.   BUFPACK(trnum,p);
  235.   BUFPACK(sn,p);
  236.   do
  237.     {
  238.       p = (u2_t *) sbuf.mtext + 2; 
  239.       if ((count + n) > lnum)
  240.         n = lnum - count;
  241.       BUFPACK(n,p);
  242.       for (i = 0; i < n; i++)
  243.         *p++ = *mpn++;
  244.       count += n;
  245.       __MSGSND(msqidb, &sbuf, (3 + n) * size2b, 0,"TRN.msgsnd: UNLKPG to BUF");
  246.       __MSGRCV(msqidb, &rbuf, sizeof (i4_t), trnum, 0,"TRN.msgrcv: UNLKPG from BUF");
  247.       cost += 1;
  248.     }
  249.   while (count < lnum);
  250. }
  251. int
  252. BUF_lockpage (u2_t sn, u2_t pn, i4_t type)
  253. {
  254.   struct msg_buf sbuf;
  255.   char *p;
  256.   i4_t   answer;
  257.   COOKMSG(LOCKPAGE,p);
  258.   *p = (type == 'x' ? STRONG:WEAK);
  259.   __MSGSND(msqidb, &sbuf, 3 * size2b + 1, 0,"TRN.msgsnd: LOCKPAGE to BUF");
  260.   __MSGRCV(msqidb, &sbuf, sizeof (i4_t), trnum, 0,
  261.            "TRN.msgrcv: LOCKPAGE from BUF");
  262.   answer = t4bunpack( sbuf.mtext);
  263.   cost += 1;
  264.   if (answer == BACKUP)
  265.     return ( -1);
  266.   else
  267.     return (0);
  268. }
  269. int
  270. BUF_enforce (u2_t sn, u2_t pn)
  271. {
  272.   struct msg_buf sbuf;
  273.   i4_t    answer;
  274.   char  *p;
  275.   COOKMSG(ENFORCE,p);
  276.   __MSGSND(msqidb, &sbuf, 3 * size2b, 0,"TRN.msgsnd: ENFORCE to BUF");
  277.   __MSGRCV(msqidb, &sbuf, sizeof (i4_t), trnum, 0,
  278.            "TRN.msgrcv: ENFORCE from BUF");
  279.   answer = *(i4_t *) sbuf.mtext;
  280.   if (answer == BACKUP)
  281.     return ( -1);
  282.   else
  283.     return (0);
  284. }
  285. void
  286. MJ_PUTBL (void)
  287. {
  288.   char *p;
  289.   struct msg_buf sbuf;
  290.   u2_t sz;
  291.   sbuf.mtype = PUTBL;
  292.   p = sbuf.mtext;
  293.   BUFPACK(trnum, p);
  294.   sz = blmj.razm = pbufmj - bufmj;
  295.   BUFPACK(sz, p);
  296.   bcopy (bufmj, p, sz);
  297.   sz += 2 * size2b;
  298.   assert (sz < SZMSGBUF);
  299.   __MSGSND(msqidm, &sbuf, sz, 0,"TRN.msgsnd: MJ PUTBL");
  300.   __MSGRCV(msqidm, &sbuf, adjsize, trnum, 0,"TRN.msgrcv: Answer from MJ");
  301.   TUPACK(sbuf.mtext,admj);
  302.   pbufmj = bufmj;
  303. }
  304. void
  305. LJ_put (i4_t type)
  306. {
  307.   char *p;
  308.   struct msg_buf sbuf;
  309.   u2_t sz;
  310.   sbuf.mtype = type;
  311.   p = sbuf.mtext;
  312.   BUFPACK(trnum, p);
  313.   sz = bllj.razm;
  314.   BUFPACK(sz, p);
  315.   bcopy (pbuflj, p, sz);
  316.   sz += 2 * size2b;
  317.   assert (sz < SZMSGBUF);
  318.   __MSGSND(msqidl, &sbuf, sz, 0,"TRN.msgsnd: LJ PUT");
  319.   __MSGRCV(msqidl, &sbuf, adjsize, trnum, 0,"TRN.msgrcv: Answer from LJ");
  320.   TUPACK(sbuf.mtext,adlj);
  321. }