OSDN Git Service

New beos files. FAQ cleanup.
authorBruce Momjian <bruce@momjian.us>
Sat, 7 Oct 2000 14:16:02 +0000 (14:16 +0000)
committerBruce Momjian <bruce@momjian.us>
Sat, 7 Oct 2000 14:16:02 +0000 (14:16 +0000)
doc/src/FAQ/FAQ.html
doc/src/sgml/ref/begin.sgml
src/backend/port/beos/Makefile [new file with mode: 0644]
src/backend/port/beos/sem.c [new file with mode: 0644]
src/backend/port/beos/shm.c [new file with mode: 0644]
src/backend/port/beos/support.c [new file with mode: 0644]

index 0c16194..4c816e7 100644 (file)
@@ -950,7 +950,7 @@ Guttman, A. "R-trees: A Dynamic Index Structure for Spatial Searching."
 Proc of the 1984 ACM SIGMOD Int'l Conf on Mgmt of Data, 45-57.<P>
 
 You can also find this paper in Stonebraker's "Readings in Database
-Systems"<P>
+Systems".<P>
 
 Built-in R-trees can handle polygons and boxes.  In theory, R-trees can
 be extended to handle higher number of dimensions.  In practice,
index 8f7eae3..86b6620 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/begin.sgml,v 1.11 2000/03/27 17:14:42 thomas Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/begin.sgml,v 1.12 2000/10/07 14:16:01 momjian Exp $
 Postgres documentation
 -->
 
@@ -103,7 +103,7 @@ NOTICE:  BEGIN: already a transaction in progress
    and a commit is implicitly performed at the end of the statement
    (if execution was successful, otherwise a rollback is done).
    <command>BEGIN</command> initiates a user transaction in chained mode,
-   i.e. all user statements after <command>BEGIN</command> command will
+   i.e., all user statements after <command>BEGIN</command> command will
    be executed in a single transaction until an explicit 
    <xref linkend="sql-commit-title" endterm="sql-commit-title">,
    <xref linkend="sql-rollback-title" endterm="sql-rollback-title">,
diff --git a/src/backend/port/beos/Makefile b/src/backend/port/beos/Makefile
new file mode 100644 (file)
index 0000000..92e1125
--- /dev/null
@@ -0,0 +1,31 @@
+#-------------------------------------------------------------------------
+#
+# Makefile--
+#    Makefile for port/beos
+#
+#-------------------------------------------------------------------------
+
+top_builddir = ../../../..
+include ../../../Makefile.global
+
+INCLUDE_OPT = 
+
+CFLAGS+=$(INCLUDE_OPT)
+
+OBJS = sem.o shm.o support.o
+
+all: SUBSYS.o 
+
+SUBSYS.o: $(OBJS)
+       $(LD) $(LDREL) $(LDOUT) SUBSYS.o $(OBJS)
+
+depend dep:
+       $(CC) -MM $(INCLUDE_OPT) *.c >depend
+
+clean: 
+       rm -f SUBSYS.o $(OBJS) 
+
+ifeq (depend,$(wildcard depend))
+include depend
+endif
+
diff --git a/src/backend/port/beos/sem.c b/src/backend/port/beos/sem.c
new file mode 100644 (file)
index 0000000..b67cf82
--- /dev/null
@@ -0,0 +1,224 @@
+/*-------------------------------------------------------------------------
+ *
+ * sem.c
+ *       BeOS System V Semaphores Emulation
+ *
+ * Copyright (c) 1999-2000, Cyril VELTER
+ * 
+ *-------------------------------------------------------------------------
+ */
+
+
+#include "postgres.h"
+#include "stdio.h"
+#include "errno.h"
+#include "OS.h"
+
+// Controle d'un pool de sémaphores
+// On considere que le semId utilisé correspond bien a une area de notre adress space
+// Les informations du pool de sémaphore sont stockés dans cette area
+int semctl(int semId,int semNum,int flag,union semun semun)
+{
+       
+       // Recherche de l'adresse de base de l'area
+       int32* Address;
+       area_info info; 
+//     printf("semctl : semid  %d, semnum %d, cmd %d\n",semId,semNum,flag);
+       if (get_area_info(semId,&info)!=B_OK)
+       {
+//             printf("area not found\n");
+               errno=EINVAL;
+               return -1;
+       }
+       Address=(int32*)info.address;
+       
+       // semnum peut etre égal à 0
+       // semun.array contient la valeur de départ du sémaphore
+       
+       // si flag = set_all il faut définir la valeur du sémaphore sue semun.array
+       if (flag==SETALL)
+       {
+               long i;
+//             printf("setall %d\n",Address[0]);
+               for (i=0;i<Address[0];i++)
+               {
+                       int32 cnt;
+                       get_sem_count(Address[i+1],&cnt);
+//                     printf("Set de ALl %d  %d = %d\n",Address[i+1],semun.array[i],cnt);
+                       cnt-=semun.array[i];
+                       if (cnt > 0)
+                               acquire_sem_etc(Address[i+1],cnt,0,0);
+                       if (cnt < 0)
+                               release_sem_etc(Address[i+1],-cnt,0);
+               }
+               return 1;
+       }
+       
+       /* si flag = SET_VAL il faut définir la valeur du sémaphore sur semun.val*/
+       if (flag==SETVAL)
+       {
+               int32 cnt;
+               get_sem_count(Address[semNum+1],&cnt);
+//             printf("semctl set val id : %d val : %d = %d\n",semId,semun.val,cnt);
+               cnt-=semun.val;
+               if (cnt > 0)
+                       acquire_sem_etc(Address[semNum+1],cnt,0,0);
+               if (cnt < 0)
+                       release_sem_etc(Address[semNum+1],-cnt,0);
+               return 1;
+       }
+       
+       /* si flag=rm_id il faut supprimer le sémaphore*/
+       if (flag==IPC_RMID)
+       {
+               long i;
+               // Suppression des sémaphores (ils appartienent au kernel maintenant)
+               thread_info ti;
+//             printf("remove set\n");
+               get_thread_info(find_thread(NULL),&ti);
+               for (i=0;i<Address[0];i++)
+               {
+                       set_sem_owner(Address[i+1],ti.team);
+                       delete_sem(Address[i+1]);
+               }
+               // Il faudrait supprimer en boucle toutes les area portant le même nom
+               delete_area(semId);
+               return 1;
+       }
+       
+       /* si flag = GETNCNT il faut renvoyer le semaphore count*/
+       if (flag==GETNCNT)
+       {
+//             printf("getncnt : impossible sur BeOS\n");
+               return 0; // a faire (peut etre impossible sur Beos)
+       }
+       
+       /* si flag = GETVAL il faut renvoyer la valeur du sémaphore*/
+       if (flag==GETVAL)
+       {
+               int32 cnt;
+               get_sem_count(Address[semNum+1],&cnt);
+//             printf("semctl getval id : %d cnt : %d\n",semId,cnt);
+               return cnt;
+       }
+//     printf("semctl erreur\n");
+       return 0;
+}
+
+// L'area dans laquelle est stockée le pool est identifiée par son nom (convention à moi : SYSV_IPC_SEM : "semId)
+int semget(int semKey, int semNum, int flags)
+{
+       char Nom[50];
+       area_id parea;
+       void* Address;
+
+//     printf("semget get k: %d n: %d fl:%d\n",semKey,semNum,flags);
+       // Construction du nom que doit avoir l'area
+       sprintf(Nom,"SYSV_IPC_SEM : %d",semKey);
+
+       // Recherche de l'area
+       parea=find_area(Nom);
+
+       // L'area existe
+       if (parea!=B_NAME_NOT_FOUND)
+       {
+//             printf("area found\n");
+               // On demande une creatrion d'un pool existant : erreur
+               if ((flags&IPC_CREAT)&&(flags&IPC_EXCL))
+               {
+//                     printf("creat asking exist\n");
+                       errno=EEXIST;
+                       return -1;
+               }
+               
+               // Clone de l'area et renvoi de son ID          
+               parea=clone_area(Nom,&Address,B_ANY_ADDRESS,B_READ_AREA | B_WRITE_AREA,parea);
+               return parea;
+       }
+       // L'area n'existe pas
+       else
+       {
+//             printf("set don't exist\n");
+               // Demande de creation
+               if (flags&IPC_CREAT)
+               {
+                       int32* Address;
+                       thread_info ti;
+                       void* Ad;
+                       long i;
+
+//                     printf("create set\n");
+                       // On ne peut pas creer plus de 500 semaphores dans un pool (limite tout à fait arbitraire de ma part)
+                       if (semNum>500)
+                       {
+                               errno=ENOSPC;
+                               return -1;
+                       }
+                                       
+                       // Creation de la zone de mémoire partagée
+                       parea=create_area(Nom,&Ad,B_ANY_ADDRESS,4096,B_NO_LOCK,B_READ_AREA | B_WRITE_AREA);             
+                       if ((parea==B_BAD_VALUE)|| (parea==B_NO_MEMORY)||(parea==B_ERROR))
+                       {
+                               errno=ENOMEM;
+                               return -1;
+                       }
+                       Address=(int32*)Ad;
+                       Address[0]=semNum;
+                       for (i=1;i<=Address[0];i++)
+                       {
+                               // Creation des sémaphores 1 par 1
+                               Address[i]=create_sem(0,Nom);
+                               
+                               if ((Address[i]==B_BAD_VALUE)|| (Address[i]==B_NO_MEMORY)||(Address[i]==B_NO_MORE_SEMS))
+                               {
+                                       errno=ENOMEM;
+                                       return -1;
+                               }
+                       }
+
+//                     printf("returned %d\n",parea);
+                       return parea;
+               }
+               // Le pool n'existe pas et pas de demande de création
+               else
+               {
+//                     printf("set does not exist no creat requested\n");
+                       errno=ENOENT;
+                       return -1;
+               }
+       }
+}
+
+// Opération sur le pool de sémaphores
+int semop(int semId, struct sembuf *sops, int nsops)
+{
+       // Recherche de l'adresse du pool
+       int32* Address;
+       area_info info; 
+       long i;
+
+//     printf("semop id : %d n: %d\n",semId,sops->sem_op);
+       get_area_info(semId,&info);
+       Address=(int32*)info.address;
+       if ((semId==B_BAD_VALUE)||(semId==B_NO_MEMORY)||(semId==B_ERROR))
+       {
+               errno=EINVAL;
+               return -1;
+       }
+
+       // Execution de l'action
+       for(i=0;i<nsops;i++)
+       {
+
+//             printf("semid %d, n %d\n",Address[sops[i].sem_num+1],sops[i].sem_op);
+               if (sops[i].sem_op < 0)
+               {
+                       acquire_sem_etc(Address[sops[i].sem_num+1],-sops[i].sem_op,0,0);
+               }
+               if (sops[i].sem_op > 0)
+               {
+                       release_sem_etc(Address[sops[i].sem_num+1],sops[i].sem_op,0);
+               }
+       }
+       return 0;
+}
diff --git a/src/backend/port/beos/shm.c b/src/backend/port/beos/shm.c
new file mode 100644 (file)
index 0000000..91e6756
--- /dev/null
@@ -0,0 +1,112 @@
+/*-------------------------------------------------------------------------
+ *
+ * shm.c
+ *       BeOS System V Shared Memory Emulation
+ *
+ * Copyright (c) 1999-2000, Cyril VELTER
+ * 
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+#include "stdio.h"
+#include "OS.h"
+
+// Detachement d'une zone de mémoire partagée
+// On detruit le clone de l'area dans notre adress-space
+int shmdt(char* shmaddr)
+{
+       // Recherche de l'id de l'area présente à cette adresse
+       area_id s;
+       s=area_for(shmaddr);
+//     printf("detach area %d\n",s);
+       
+       // Suppression de l'area
+       return delete_area(s);
+}
+
+// Attachement à une zone de mémoire partagée
+// L'area doit bien partie de notre adress-space et on retourne directement l'adress
+int* shmat(int memId,int m1,int m2)
+{
+//     printf("shmat %d %d %d\n",memId,m1,m2);
+
+       // Lecture de notre team_id
+       thread_info thinfo;
+       team_info teinfo;
+       area_info ainfo; 
+       
+       get_thread_info(find_thread(NULL),&thinfo);
+       get_team_info(thinfo.team,&teinfo);
+       
+       // Lecture du teamid de l'area
+       if (get_area_info(memId,&ainfo)!=B_OK)
+               printf("AREA %d Invalide\n",memId);
+       
+       if (ainfo.team==teinfo.team)
+       {
+               //retour de l'adresse
+//             printf("attach area %d add %d\n",memId,ainfo.address);
+               return (int*)ainfo.address;
+       }       
+       else
+       {
+               // Clone de l'area
+               area_id narea;
+               narea = clone_area(ainfo.name,&(ainfo.address),B_CLONE_ADDRESS,B_READ_AREA | B_WRITE_AREA,memId);       
+               get_area_info(narea,&ainfo);    
+//             printf("attach area %d in %d add %d\n",memId,narea,ainfo.address);
+               return (int*)ainfo.address;
+       }
+}
+
+// Utilisé uniquement pour supprimer une zone de mémoire partagée
+// On fait la meme chose que le detach mais avec un id direct
+int shmctl(int shmid,int flag, struct shmid_ds* dummy)
+{
+//     printf("shmctl %d %d \n",shmid,flag);
+       delete_area(shmid);
+       return 0;
+}
+
+// Recupération d'une area en fonction de sa référence
+// L'area source est identifiée par son nom (convention à moi : SYSV_IPC_SHM : "memId)
+int shmget(int memKey,int size,int flag)
+{
+       int32 n_size;
+       char nom[50];
+       area_id parea;
+       void* Address;
+       area_id a;
+       
+       n_size=((size/4096)+1)*4096;
+
+//     printf("shmget %d %d %d %d\n",memKey,size,flag,nsize);
+
+       // Determination du nom que doit avoir l'area
+       sprintf(nom,"SYSV_IPC_SHM : %d",memKey);
+
+
+       // Recherche de cette area
+       parea=find_area(nom);
+       
+       // L'area existe
+       if (parea!=B_NAME_NOT_FOUND)
+       {
+//             printf("area found\n");
+               return parea;
+       }       
+
+       // L'area n'existe pas et on n'en demande pas la création : erreur
+       if (flag==0)
+       {
+//             printf("area %s not found\n",nom);
+               return -1;
+       }
+       
+       // L'area n'existe pas mais on demande sa création
+       a=create_area(nom,&Address,B_ANY_ADDRESS,n_size,B_NO_LOCK,B_READ_AREA | B_WRITE_AREA);          
+//     printf("area %s : %d created addresse %d\n",nom,a,Address);
+       return a;
+}
+
diff --git a/src/backend/port/beos/support.c b/src/backend/port/beos/support.c
new file mode 100644 (file)
index 0000000..d517dd7
--- /dev/null
@@ -0,0 +1,258 @@
+/*-------------------------------------------------------------------------
+ *
+ * support.c
+ *       BeOS Support functions
+ *
+ * Copyright (c) 1999-2000, Cyril VELTER
+ * 
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+
+/* Support Globals */
+char* self_binary=NULL;
+port_id beos_dl_port_in=0;
+port_id beos_dl_port_out=0;
+sem_id beos_shm_sem;
+
+image_id beos_dl_open(char * filename)
+{
+       image_id im;
+
+       /* Start the support server */
+       if (self_binary==NULL)
+       {
+               /* Can't start support server without binary name */            
+               elog(NOTICE, "Error loading BeOS support server : can't find binary");                          
+               return B_ERROR;
+       }
+       else
+       {
+               /* If a port doesn't exist, lauch support server */ 
+               if ((beos_dl_port_in<=0)||(beos_dl_port_out<=0))
+               {
+                       /* Create communication port */
+                       beos_dl_port_in=create_port(50,"beos_support_in");
+                       beos_dl_port_out=create_port(50,"beos_support_in");
+
+
+                       if ((beos_dl_port_in<=0)||(beos_dl_port_out<=0))
+                       {
+                               elog(NOTICE, "Error loading BeOS support server : can't create communication ports");                           
+                               return B_ERROR;
+                       }
+                       else
+                       {
+                               char Cmd[4000]; 
+                       
+                               /* Build arg list */
+                               sprintf(Cmd,"%s -beossupportserver %d %d &",self_binary,(int)beos_dl_port_in,(int)beos_dl_port_out);
+       
+                               /* Lauch process */
+                               system(Cmd);
+                       }
+               }
+       }
+       
+       /* Add-on loading */
+       
+       /* Send command '1' (load) to the support server */
+       write_port(beos_dl_port_in,1,filename,strlen(filename)+1);
+       
+       /* Read Object Id */
+       read_port(beos_dl_port_out,&im,NULL,0);
+
+       /* Checking integrity */
+       if (im<0)
+       {       
+               elog(NOTICE, "Can't load this add-on ");
+               return B_ERROR; 
+       }
+       else
+       {
+               /* Map text and data segment in our address space */
+               char datas[4000];
+               int32 area;
+               int32 resu;
+               void* add;
+       
+               /* read text segment id and address */
+               read_port(beos_dl_port_out,&area,datas,4000);
+               read_port(beos_dl_port_out,(void*)&add,datas,4000);
+               /* map text segment in our address space */
+               resu=clone_area(datas,&add,B_EXACT_ADDRESS,B_READ_AREA|B_WRITE_AREA,area);
+               if (resu<0)
+               {
+                       /* If we can't map, we are in reload case */
+                       /* delete the mapping */
+                       resu=delete_area(area_for(add));
+                       /* Remap */
+                       resu=clone_area(datas,&add,B_EXACT_ADDRESS,B_READ_AREA|B_WRITE_AREA,area);
+                       if (resu<0)
+                       {
+                               elog(NOTICE, "Can't load this add-on : map text error");
+                       }
+               }
+               
+               /* read text segment id and address */
+               read_port(beos_dl_port_out,&area,datas,4000);
+               read_port(beos_dl_port_out,(void*)&add,datas,4000);
+               /* map text segment in our address space */
+               resu=clone_area(datas,&add,B_EXACT_ADDRESS,B_READ_AREA|B_WRITE_AREA,area);
+               if (resu<0)
+               {
+                       /* If we can't map, we are in reload case */
+                       /* delete the mapping */
+                       resu=delete_area(area_for(add));
+                       /* Remap */
+                       resu=clone_area(datas,&add,B_EXACT_ADDRESS,B_READ_AREA|B_WRITE_AREA,area);
+                       if (resu<0)
+                       {
+                               elog(NOTICE, "Can't load this add-on : map data error");
+                       }
+               }
+               
+               return im;
+       }
+}
+
+status_t beos_dl_close(image_id im)
+{
+       /* unload add-on */
+       int32 resu;
+       write_port(beos_dl_port_in,2,&im,4);
+       read_port(beos_dl_port_out,&resu,NULL,0);
+       return resu;
+}
+
+/* Main support server loop */
+
+void beos_startup(int argc,char** argv)
+{
+       if (strlen(argv[0]) >= 10 && !strcmp(argv[0] + strlen(argv[0]) - 10, "postmaster"))
+       {
+               /* Shared memory cloning protection semaphore */
+               beos_shm_sem=create_sem(1,"beos_shm_sem");      
+       }
+
+       if (argc > 1 && strcmp(argv[1], "-beossupportserver") == 0)
+       {
+               port_id port_in;
+               port_id port_out;
+               
+               /* Get back port ids from arglist */
+               sscanf(argv[2],"%d",(int*)(&port_in));
+               sscanf(argv[3],"%d",(int*)(&port_out));
+                       
+               /* Main server loop */
+               for (;;)
+               { 
+                       int32 opcode=0;
+                       char datas[4000];
+       
+                       /* Wait for a message from the backend :
+                       1 : load a shared object 
+                       2 : unload a shared object
+                       any other : exit support server */
+                       read_port(port_in,&opcode,datas,4000);
+       
+                       switch(opcode)
+                       {
+                               image_id addon;
+                               image_info info_im;
+                               area_info info_ar;
+       
+                               /* Load Add-On */
+                               case 1 :
+               
+                                       /* Load shared object */
+                                       addon=load_add_on(datas);
+               
+                                       /* send back the shared object Id */
+                                       write_port(port_out,addon,NULL,0);
+                                       
+                                       /* Get Shared Object infos */
+                                       get_image_info(addon,&info_im);
+       
+                                       /* get text segment info */
+                                       get_area_info(area_for(info_im.text),&info_ar);
+                                       /* Send back area_id of text segment */
+                                       write_port(port_out,info_ar.area,info_ar.name,strlen(info_ar.name)+1);
+                                       /* Send back real address of text segment */
+                                       write_port(port_out,(int)info_ar.address,info_ar.name,strlen(info_ar.name)+1);
+                       
+                                       
+                                       /* get data segment info */
+                                       get_area_info(area_for(info_im.data),&info_ar);
+                                       /* Send back area_id of data segment */
+                                       write_port(port_out,info_ar.area,info_ar.name,strlen(info_ar.name)+1);
+                                       /* Send back real address of data segment */
+                                       write_port(port_out,(int)info_ar.address,info_ar.name,strlen(info_ar.name)+1);
+                               break;
+                               /* UnLoad Add-On */
+                               case 2 :
+                                       /* Unload shared object and send back the result of the operation */
+                                       write_port(port_out,unload_add_on(*((int*)(datas))),NULL,0);
+                               break;
+                               /* Cleanup and exit */
+                               default:
+                                       /* Free system resources */
+                                       delete_port(port_in);
+                                       delete_port(port_out);
+                                       /* Exit */
+                                       exit(0);
+                               break;
+                       }
+               }
+               /* Never be there */
+               exit(1);
+       }
+}
+
+
+void beos_backend_startup(char * binary)
+{
+       team_id ct;
+       thread_info inft;
+       char nom[50];
+       char nvnom[50];
+       area_info inf;
+       int32 cook=0;
+
+       /* remember full path binary name to load dl*/
+       self_binary=strdup(binary);
+
+       /* find the current team */
+       get_thread_info(find_thread(NULL),&inft);
+       ct=inft.team;
+       
+       /* find all area with a name begining by pgsql and destroy / clone then */
+
+       /* This operation must be done by only one backend at a time */
+       if(acquire_sem(beos_shm_sem)==B_OK)
+       {
+               while (get_next_area_info(0, &cook, &inf) == B_OK)
+               {
+                       strcpy(nom,inf.name);
+                       strcpy(nvnom,inf.name);
+                       nom[9]=0;
+                       nvnom[5]='i';
+                       if (!strcmp(nom,"SYSV_IPC_"))
+                       {
+                               void* add;
+                               area_id ar;
+                               add=inf.address;
+                               delete_area(inf.area);
+                               ar=find_area(inf.name);
+                               clone_area(nvnom,&add,B_CLONE_ADDRESS,B_READ_AREA|B_WRITE_AREA,ar);
+                       }
+               } 
+               release_sem(beos_shm_sem);
+       }
+       else
+       {
+               /* Fatal error, exiting with error */
+               exit(1);
+       }
+}