mirror of https://github.com/postgres/postgres
parent
949529481e
commit
a759460178
@ -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 |
||||
|
||||
@ -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; |
||||
} |
||||
@ -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; |
||||
} |
||||
|
||||
@ -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); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue