⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bufipc.c

📁 免费的Sql数据库系统
💻 C
字号:
/* *  bufipc.c  - Buffer communication functions  *              Kernel of GNU SQL-server. Buffer * * This file is a part of GNU SQL Server * *  Copyright (c) 1996, 1997, Free Software Foundation, Inc *  Developed at the Institute of System Programming *  This file is written by  Vera Ponomarenko * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * *  Contacts:   gss@ispras.ru * *//* $Id: bufipc.c,v 1.246 1997/03/31 11:05:20 kml Exp $ */#include "setup_os.h"#ifdef HAVE_SYS_FILES_H#include <sys/file.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#include <sys/times.h>#include "fdeclbuf.h"#include <sys/msg.h>#include <sys/shm.h>#ifdef HAVE_FCNTL_H#include <fcntl.h>#endif#ifdef STDC_HEADERS#include <string.h>#else#include <strings.h>#endif#include "rnmtp.h"#include "inpop.h"#include "pupsi.h"#include "pupans.h"#include "bufdefs.h"#include "strml.h"#include "totdecl.h"#ifndef CLK_TCK#define CLK_TCK 60#endif#define PRINT(x, y) /* printf(x, y); */#define size4b sizeof(i4_t)#define size2b sizeof(i2_t)static struct tms buffer;static i4_t tt, buftime;extern i4_t errno;i4_t msqidm, msqidbf;i4_t MAXNBUF, MAXTACT, MAXNOP, MAXSEGNUM;key_t FSEGNUM;i4_t N_buf, N_opt;char PRXR = 0;i4_t *fdseg;char **tabdseg;char **seg_file_name;i4_t N_seg;pid_t parent;i4_t max_buffers_number;u2_t I_fix = NO;		/* indicator of fixation */i4_t N_log = 0;			/* number of operations by log */i4_t N_op = 0;			/* number of ended operations */#define ARG(num, what, type)   sscanf (argv[num], "%d", &argum); \                               what = (type)(argum)voidmain (i4_t argc, char **argv){  i4_t i, k;  i4_t n;  key_t keymj, keybf;  i4_t argum;    MEET_DEBUGGER;  setbuf (stdout, NULL);  ARG(2, keybf, key_t);  ARG(3, keymj, key_t);  ARG(4, N_opt, i4_t);  ARG(5, MAXNBUF, i4_t);  ARG(6, MAXTACT, i4_t);  ARG(7, MAXNOP, i4_t);  ARG(8, FSEGNUM, key_t);  ARG(argc - 1, parent, pid_t);  /*    * reading DB segments information    */  for (i = 9, n = 0; i < argc - 1; i += 2)    {      if (!sscanf (argv[i], "%d", &k))	break;      if (n < k)	n = k;    }  /* 'n' contains the maximum number of segment */  MAXSEGNUM = n + 1;  /* allocating space for segment information */  fdseg         = (i4_t *)  xmalloc (MAXSEGNUM * sizeof (i4_t));  seg_file_name = (char **) xmalloc (MAXSEGNUM * sizeof (char **));  for (i = 0; i < MAXSEGNUM ; i++)    {      fdseg[i] = -1;      seg_file_name[i] = NULL;    }  seg_file_name[0] = xmalloc (strlen (argv[1]));  strcpy (seg_file_name[0], argv[1]);    for (i = 9; i < argc - 1; i+=2)    {      sscanf (argv[i], "%d", &k);      seg_file_name[k] = xmalloc (strlen (argv[i+1]));      strcpy (seg_file_name[k], argv[i+1]);    }  /*---------------------------------------------------------*/  if ((msqidbf = msgget (keybf, IPC_CREAT | DEFAULT_ACCESS_RIGHTS)) < 0)    {      perror ("BUF.msgget: Queue for BUF");      exit (1);    }  MSG_INIT (msqidm, keymj, "MJ");  init_hash ();  tabdseg = (char **) xmalloc (MAXNBUF * sizeof (char *));  for (i = 0; i < MAXNBUF; i++)    tabdseg[i] = NULL;  max_buffers_number = MAXNBUF;  N_buf = 0;  N_seg = 0;    for (;;)    {      msg_rcv ();      tact ();    }}#define UNPACKMSG(p) { BUFUPACK(p,trnum);BUFUPACK(p,segn);BUFUPACK(p,pn);}voidmsg_rcv (void){  struct msg_buf rbuf;  u2_t trnum, pn, segn;  char *p, *p1;  register i4_t op;  i4_t admj;  struct BUFF *buf;  rbuf.mtype = 0;        PRINT ("BUF.msg_rcv: msqidbf = %d\n", (i4_t)msqidbf)    __MSGRCV(msqidbf, &rbuf, SZMSGBUF, -(ANSBUF - 1), 0,"BUF.msgrcv");        PRINT ("BUF.msg_rcv: rbuf.mtype = %d\n", rbuf.mtype)        times (&buffer);  tt = buffer.tms_utime;  op = rbuf.mtype;  p = rbuf.mtext;  switch (op)    {    case INIFIXB:      inifixb (t4bunpack (p), t4bunpack (p + size4b));      break;    case GETPAGE:      UNPACKMSG(p);      buf = get (segn, pn, 'r');      buf_to_user (trnum, (key_t) buf->b_seg->keyseg);      break;    case PUTPAGE:      UNPACKMSG(p);      BUFUPACK(p,admj);      put (segn, pn, admj, *p);      user_p (trnum, 0);      break;    case LOCKPAGE:      UNPACKMSG(p);      if (segn >= (u2_t) MAXSEGNUM || seg_file_name[segn] == NULL)	user_p (trnum, NO_SUCH_SEG);      else	{          PRINTF (("BUF.msg_rcv: LOCKPAGE segn=%d,pn = %d,f_name=%s\n",                  segn, pn, seg_file_name[segn]));	  if (buflock (trnum, segn, pn, *p, 0) == 0)	    user_p (trnum, 0);	}      break;    case ENFORCE:      UNPACKMSG(p);      if (enforce (trnum, segn, pn) == 0)	user_p (trnum, 0);      break;    case UNLKPG:      UNPACKMSG(p);      unlock (segn, pn, p);      user_p (trnum, 0);      break;    case NEWGET:      UNPACKMSG(p);      buf = get (segn, pn, 'n');      buf_to_user (trnum, (key_t) buf->b_seg->keyseg);      break;    case LOCKGET:      UNPACKMSG(p);      if (segn >= (u2_t) MAXSEGNUM || seg_file_name[segn] == NULL)	buf_to_user (trnum, (key_t)NO_SUCH_SEG);      else if (buflock (trnum, segn, pn, *p, 1) == 0)        {          buf = get (segn, pn, 'r');          buf_to_user (trnum, (key_t) buf->b_seg->keyseg);	}      break;    case PUTUNL:      p1 = p + 2 * size2b;      UNPACKMSG(p);      BUFUPACK(p,admj);      put (segn, pn, admj, *p);      unlock (segn, 1, p1);      user_p (trnum, 0);      break;    case ENDOP:      end_op ();      break;    case BEGTACT:      tact ();      break;    case OPTNUM:      optimal (t4bunpack (p));      MAXTACT = t4bunpack (p + size4b);      break;    case FINIT:      finit ();      break;    default:      printf ("BUF.msg_rcv: No such operation in interface BUF\n");      break;    }  times (&buffer);  tt = buffer.tms_utime - tt;  buftime += tt;}voidbuf_to_user (u2_t trnum, key_t keys){  struct msg_buf sbuf;  sbuf.mtype = trnum;  TPACK(keys, sbuf.mtext);  __MSGSND(msqidbf, &sbuf, sizeof (key_t), 0,"BUF.msgsnd: Answer TRN");}voiduser_p (u2_t trnum, i4_t type){  struct msg_buf sbuf;  sbuf.mtype = trnum;  TPACK(type, sbuf.mtext);  __MSGSND(msqidbf, &sbuf, size4b, 0,"BUF.msgsnd: Answer TRN");}/*  Functions realizing calls of Microlog */i4_t cur_endmj = NULL_MICRO;	/* current end of microlog */i4_t pushaddmj = NULL_MICRO;	/* last push MJ address */voidpush_micro (i4_t addr)		/* push microlog buffer */{  u2_t pn, pn_push, off, off_push;  char *a, *b;  a = (char *) &addr;  b = (char *) &pushaddmj;  pn = t2bunpack (a);  pn_push = t2bunpack (b);  off = t2bunpack (a + size2b);  off_push = t2bunpack (b + size2b);  if (pn > pn_push)    {      pushmicro (addr);    }  else if (pn == pn_push && off > off_push)    {      pushmicro (addr);    }}voidpushmicro (i4_t addr){  struct msg_buf sbuf;  sbuf.mtype = OUTDISK;  t4bpack (addr, sbuf.mtext);  __MSGSND(msqidm, &sbuf, size4b, 0,"BUF.msgsnd: OUTDISK");  __MSGRCV(msqidm, &sbuf, 0, ANSMJ, 0,"BUF.msgrcv");  pushaddmj = addr;}struct des_seg *new_seg (void)			/* Create a segment */{  register i4_t i;  struct des_seg *desseg;  key_t key;  i4_t shmid;  for (i = 0; i < max_buffers_number; i++)    if ((desseg = (struct des_seg *) tabdseg[i]) == NULL)      {        desseg = (struct des_seg *) get_empty (sizeof (struct des_seg));        key = FSEGNUM + i;        while ((shmid = shmget (key, BD_PAGESIZE,                                IPC_CREAT | DEFAULT_ACCESS_RIGHTS)) < 0)          {            if ( (N_buf + 1) < N_opt)              fprintf (stderr, "BUF.new_seg: number of buffers is "                       "less optimal number of buffers\n");            waitfor_seg (N_buf - 1);            max_buffers_number = N_buf;            /*                        perror ("BUF.shmget");            exit (1);            */          }        desseg->keyseg = key;        desseg->idseg = shmid;        tabdseg[i] = (char *) desseg;        N_seg++;        return (desseg);              }  return (NULL);  }voiddel_seg (struct des_seg *desseg){  struct shmid_ds shmstr;  register i4_t i;    shmctl (desseg->idseg, IPC_RMID, &shmstr);  for (i = 0; i < MAXNBUF; i++)    if (desseg == (struct des_seg *) tabdseg[i])      {	tabdseg[i] = NULL;        break;      }  xfree (desseg);  N_seg--;}/*****************************************************************************                                FIXATION*/voidinifixb (i4_t nop, i4_t ljadd){  struct msg_buf sbuf;  N_log = nop;  if (N_op != N_log)    fix_mode ();  push_micro (cur_endmj);  do_fix ();  sbuf.mtype = DOFIX;		/* Fixation */  t4bpack (ljadd, sbuf.mtext);  t4bpack (PRXR, (char*)sbuf.mtext+size4b);  __MSGSND(msqidm, &sbuf, size4b + 1, 0,"BUF.msgsnd: DOFIX");  __MSGRCV(msqidm, &sbuf, 0, ANSMJ, 0,"BUF.msgrcv");  I_fix = NO;  N_op = 0;  sbuf.mtype = ANSBUF;  t4bpack (0, sbuf.mtext);  __MSGSND(msqidbf, &sbuf, sizeof (i4_t), 0,"BUF.msgsnd: ANSLJ");}/**************************** real fixation *********************************/extern struct BUFF *prios[PRIORITIES];	/* priority rings */voiddo_fix (void){  u2_t prio;  struct BUFF *buf;  for (prio = 0; prio < PRIORITIES; prio++)    if ((buf = prios[prio]) != NULL)      do	{	  push_buf (buf);	  buf = buf->b_next;	}      while (buf != prios[prio]);  cur_endmj = NULL_MICRO;  pushaddmj = NULL_MICRO;}/**************************** fixation mode *********************************/voidfix_mode (void){  I_fix = YES;  while (N_op != N_log)    msg_rcv ();}/*************************** end of operation *******************************/voidend_op (void){  N_op++;}/****************************** weak error **********************************/voidweak_err (char *text){  printf ("%s.\n", text);}/***************************** read/write buffer ********************************/voidread_buf (struct BUFF *buf){  u2_t segn, pn;  char *shm;  off_t n;  i4_t fd;  segn = buf->b_page->p_seg;  pn = buf->b_page->p_page;  if (fdseg[segn] < 0)    if ((fdseg[segn] = open (seg_file_name[segn], O_RDWR, 0644)) < 0)      {        printf ("BUF.read_buf: seg_file_name = %s\n", seg_file_name[segn]);	perror ("SEGFILE: open error");	exit (1);      }  fd = fdseg[segn];   if ((n = lseek (fd, BD_PAGESIZE * pn, SEEK_SET)) < 0)    {/*      printf ("BUF.read_buf: lseek error errno=%d, fd = %d\n", errno, fdseg[segn]);*/      ADM_ERRFU (MERR);    }  if ((shm = shmat (buf->b_seg->idseg, NULL, 0)) == (char *) -1)    {      perror ("BUF.shmat");      exit (1);    }  if (read (fd, shm, BD_PAGESIZE) < 0)    {      printf ("BUF.read_buf: read error errno=%d\n", errno);      ADM_ERRFU (MERR);    }  if (shmdt (shm) < 0)    {      perror ("BUF.shmdt");      exit (1);    }}voidwrite_buf (struct BUFF *buf){  u2_t segn, pn;  char *shm;  off_t n;  i4_t fd;  segn = buf->b_page->p_seg;  pn = buf->b_page->p_page;  if (fdseg[segn] < 0)    if ((fdseg[segn] = open (seg_file_name[segn], O_RDWR, 0644)) < 0)      {        printf ("BUF.write_buf: sn = %d, seg_file_name = %s\n", segn, seg_file_name[segn]);	perror ("SEGFILE: open error");	exit (1);      }  fd = fdseg[segn];  if ((n = lseek (fd, BD_PAGESIZE * pn, SEEK_SET)) < 0)    {      ADM_ERRFU (MERR);    }  if ((shm = shmat (buf->b_seg->idseg, NULL, 0)) == (char *) -1)    {      perror ("BUF.shmat");      exit (1);    }  if (write (fd, shm, BD_PAGESIZE) != BD_PAGESIZE)    ADM_ERRFU (MERR);  if (shmdt (shm) < 0)    {      perror ("BUF.shmdt");      exit (1);    }  buf->b_prmod = PRNMOD;  buf->b_micro = NULL_MICRO;}voidADM_ERRFU (i4_t p){#if 1  perror ("BUF. ERRFU");#else  struct msg_buf sbuf;  sbuf.mtype = ERRFU;  sbuf.mtext[0] = (char) p;  sbuf.mtext[1] = BF_PPS;  __MSGSND(msqida, &sbuf, 2, 0,"BUF. ERRFU");#endif}voidfinit (void){  register i4_t i;  struct shmid_ds shmstr;  struct msg_buf sbuf;  struct BUFF *buf;  for (i = 0; i < MAXSEGNUM; i++)    if (fdseg[i] >= 0)      close (fdseg[i]);  xfree ((char *) fdseg);  PRINTF (("BUF.finit: segments are closed\n"));  for (i = 0; i < MAXSEGNUM; i++)    if (seg_file_name[i] != NULL)      xfree ((char *) seg_file_name[i]);  xfree ((char *) seg_file_name);  PRINTF (("BUF.finit: seg_file_names are free \n"));  for (i = 0; i < PRIORITIES; i++)    {      PRINTF (("BUF.finit: prios[%d]=%d\n", i, (i4_t) prios[i]));      if ((buf = prios[i]) != NULL)	do	  {	    if (buf->b_seg != NULL)	      {		PRINTF (("BUF.finit: idseg=%d\n", buf->b_seg->idseg));		shmctl (buf->b_seg->idseg, IPC_RMID, &shmstr);	      }	  }	while ((buf = buf->b_next) != prios[i]);    }  PRINTF (("BUF.finit.e: buftime=%ld(msec)\n",           buffer.tms_utime * 1000 / CLK_TCK));  sbuf.mtype = ANSBUF;  sbuf.mtext[0] = 0;  __MSGSND(msqidbf, &sbuf, 1, 0,"BUF.msgsnd: Answer ADM");}voidwaitfor_seg (i4_t buf_num){  struct msg_buf rbuf;  u2_t trnum, pn, segn;  char *p, *p1;  register i4_t op;  i4_t admj;  for (; (N_buf + 1) >= buf_num;)    {      rbuf.mtype = 0;            PRINT ("BUF.waitfor_seg: msqidbf = %d\n", (i4_t)msqidbf)            __MSGRCV(msqidbf, &rbuf, BD_PAGESIZE, -(ANSBUF - 1), 0,"BUF.msgrcv");            PRINT ("BUF.waitfor_seg: rbuf.mtype = %d\n", rbuf.mtype)            op = rbuf.mtype;      p = rbuf.mtext;      switch (op)	{	case INIFIXB:	  inifixb (t4bunpack (p), t4bunpack (p + size4b));	  break;	case PUTPAGE:          UNPACKMSG(p);	  BUFUPACK(p,admj);	  put (segn, pn, admj, *p);	  user_p (trnum, 0);	  break;	case LOCKPAGE:          UNPACKMSG(p);	  if (segn >= (u2_t) MAXSEGNUM || seg_file_name[segn] == NULL)	    user_p (trnum, NO_SUCH_SEG);	  else if (buflock (trnum, segn, pn, *p, 0) == 0)            user_p (trnum, 0);	  break;	case ENFORCE:          UNPACKMSG(p);	  if (enforce (trnum, segn, pn) == 0)	    user_p (trnum, 0);	  break;	case UNLKPG:          UNPACKMSG(p);	  unlock (segn, pn, p);	  user_p (trnum, 0);	  break;	case PUTUNL:	  p1 = p + 2*size2b;          UNPACKMSG(p);	  BUFUPACK(p,admj);	  put (segn, pn, admj, *p);	  unlock (segn, 1, p1);	  user_p (trnum, 0);	  break;	case ENDOP:	  end_op ();	  break;	case BEGTACT:	  tact ();	  break;	case OPTNUM:	  optimal (t4bunpack (p));          MAXTACT = t4bunpack (p + size4b);          	  break;	case FINIT:	  finit ();	  break;	default:	  printf ("BUF.waitfor_seg: The operation op=%d is disabled\n", op);	  break;	}      tact ();    }}/******************************** the end ***********************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -