#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define MEM 568

/*Carles Pina i Estany  -  carles@pinux.info
 * Febrer 2004*/


/*Exemple de compartició de memòria*/
/*Fa un pare i 5 fills i comparteixen una regió de memòria*/

void fill ();

int main () {
	int shmid;
	int *shmptr;
	pid_t pid;
	int t;

	/*Aquí demanarà 100 bytes de memòria, els fa, dona els permisos
	 * de lectura per tothom i posa que la clau és "10" */
	
	shmid=shmget((key_t)10, MEM, IPC_CREAT|0666);
	perror("error");
	printf("Tinc el shmid: %d\n",shmid);

	/*enllaça la regió de memòria a un punter normal i corrent*/
	shmptr=shmat(shmid,0,0);

	/*poso dades*/
	for (t=0;t<50;t++) {
		shmptr[t]=2*t;
	}
	

	for (t=0;t<4;t++) {
		pid=fork();
		if (pid==0) {
			/*Som un fill*/
			fill ();
		}
		sleep(1);
		/*El primer fill veurà que shmptr[0] és 0, però
		 * els altres ja veuran 25!!!*/
		shmptr[0]=25;
	}

	sleep (15);
	printf("Sóc el pare. Ara allibero memòria\n");
	
	
	shmdt(shmptr);	/*Des-junto*/

	shmctl(shmid, IPC_RMID,0); /*Allibero el el recurs!!!!*/

	/* amb ipcs i ipcrm poden llistar i eliminar regions
	 * de memòria compartida que s'han quedat penjades...*/
	
	return (0);
}

void fill() {
	int *ptr;
	int ident,t;

	printf("Sóc un nou fill\n");
	sleep(2);
	/*Busequem l'identificador*/
	ident=shmget((key_t) 10, MEM, 0666);
	printf("Soc el fill, tinc el shmid: %d\n",ident);

	/*fem que ptr apunti al començament de l'identificador*/
	ptr=(int*)shmat(ident, NULL, 0);

	for (t=0;t<5;t++) {
		/*Si és 25 fem que sigui 1000...*/
		if (ptr[0]==25) ptr[0]=1000;
		printf("Sóc el fill. A la posició %d hi ha: %d\n",t,ptr[t]);

		sleep(1);
	}

	printf("Fi del fill\n");
	exit(0);	
			/*Forcem que acabi el fill
			  pq. sinó torna a entrar al bucle!*/
}

