Beispiel #1
0
/*------------------------------------------------------------------------
 * pipdelete  --  Delete a pipe by releasing its table entry
 *------------------------------------------------------------------------
 */
syscall	pipdelete(
	 	pipid32		pip			/* ID of semaphore to delete	*/
	)
{
	intmask	mask;				/* saved interrupt mask			*/

	mask = disable();

	if (isbadpip(pip)) {
		restore(mask);
		return SYSERR;
	}

	struct pentry *pipptr;		/* ptr to pipe table entry		*/
	
	pipptr = &piptab[pip];
	if (pipptr->pstate != PIPE_USED ||
		pipptr->powner != getpid()) {
		restore(mask);
		return SYSERR;
	}

	pipptr->pstate = PIPE_FREE;
	pipptr->powner = 0;
	pipptr->prdsem = semdelete(pipptr->prdsem);
	pipptr->pwrsem = semdelete(pipptr->pwrsem);

	restore(mask);
	return OK;
}
Beispiel #2
0
/*------------------------------------------------------------------------
 * pipread  --  Read from a pipe, blocking if empty
 *------------------------------------------------------------------------
 */
syscall	pipread(
		pipid32		pip,		/* ID of pipe to read from			*/
		char 		*buf,		/* pointer to buffer to read to		*/
		uint32		len			/* number of bytes to read 			*/
	)
{
	intmask	mask;				/* saved interrupt mask				*/

	mask = disable();

	if (isbadpip(pip)) {
		restore(mask);
		return SYSERR;
	}

	struct pentry *pipptr;		/* ptr to pipe table entry			*/
	
	pipptr = &piptab[pip];
	if (pipptr->pstate != PIPE_CONNECTED ||
		(pipptr->pend1 != getpid() && pipptr->pend2 != getpid())) {
		restore(mask);
		return SYSERR;
	}

	/* Ensure there is enough space for the entire read request */
	if (semcount(pipptr->prdsem) < len) {
		restore(mask);
		return SYSERR;
	}

	char *buffer = buf;			/* local copy of buffer				*/
	int count = 0;				/* character count for buffer		*/
	char c;						/* temporary space for characters	*/

	/* Read characters from the circular buffer */
	while (count < len)
	{
		wait(pipptr->prdsem);

		c = pipptr->pbuf[pipptr->pbufs];
		*buffer++ = c;
		pipptr->pbufc--;
		pipptr->pbufs = (pipptr->pbufs + 1) % PIPE_SIZ;
		count++;

		signal(pipptr->pwrsem);
	}

	restore(mask);
	return count;
}
Beispiel #3
0
/*------------------------------------------------------------------------
 * pipwrite  --  Write to a pipe, blocking if full
 *------------------------------------------------------------------------
 */
syscall	pipwrite(
		pipid32		pip,		/* ID of pipe to write to			*/
		char 		*buf,		/* pointer to buffer to write from	*/
		uint32		len			/* number of bytes to write			*/
	)
{
	intmask	mask;				/* saved interrupt mask				*/

	mask = disable();

	if (isbadpip(pip)) {
		restore(mask);
		return SYSERR;
	}

	struct pentry *pipptr;		/* ptr to pipe table entry			*/
	
	pipptr = &piptab[pip];
	if (pipptr->pstate != PIPE_CONNECTED ||
		(pipptr->pend1 != getpid() && pipptr->pend2 != getpid())) {
		restore(mask);
		return SYSERR;
	}

	/* Ensure there is enough space for the entire write request */
	if (semcount(pipptr->pwrsem) < len) {
		restore(mask);
		return SYSERR;
	}

	char *buffer = buf;			/* local copy of buffer				*/
	int count = 0;				/* character count for buffer		*/

	/* Write characters to the circular buffer */
	while (count < len)
	{
		wait(pipptr->pwrsem);
		
		pipptr->pbuf[(pipptr->pbufs + pipptr->pbufc) % PIPE_SIZ] = *buffer++;
		count++;
		pipptr->pbufc++;
	
		signal(pipptr->prdsem);
	}

	restore(mask);
	return count;
}
Beispiel #4
0
/*------------------------------------------------------------------------
 * pipconnect  --  Connect a pipe with a reader and writer process
 *------------------------------------------------------------------------
 */
syscall pipconnect(pipid32 pip, pid32 writer, pid32 reader)
{
	intmask mask;			/* saved interrupt mask		*/
        //kprintf("inside pipconnect \n\r");	
	mask = disable();
	if (isbadpip(pip) || isbadpid(writer) || isbadpid(reader) || (reader == writer) ) {
		restore(mask);
		return SYSERR;
	}
        if ((piptab[pip].pipstate == PIPE_CONNECTED) || (piptab[pip].pipstate == PIPE_FREE)) {
		restore(mask);
		return SYSERR;
	}

        piptab[pip].pipstate = PIPE_CONNECTED;
        piptab[pip].rdend = reader;
        piptab[pip].wrtend = writer;
        // create process table entry for pipe state
        //pipedetails(pip);
	restore(mask);
	return OK;
}
Beispiel #5
0
/*------------------------------------------------------------------------
 * pipwrite  --  Write len characters from an array into the pipe
 *------------------------------------------------------------------------
 */
syscall pipwrite(pipid32 pip, char *buf, uint32 len)
{
	intmask mask;			/* saved interrupt mask		*/
	//kprintf("inside pipwrite \n\r");
	mask = disable();
        uint32 numBytes=0;
	int32 i,j;
        uint32 wrflag=0;
        if (isbadpip(pip) || (buf == NULL) || (len < 0) ) {
		restore(mask);
		return SYSERR;
	}
        if ((piptab[pip].wrtend) != getpid()) {
		restore(mask);
		return SYSERR;
	}
        /*if((piptab[pip].nextpos == 0) && (nonempty(semtab[piptab[pip].supply].squeue)))
	{
		wrflag = 1;
	}*/
        //kprintf("Before writer while numBytes\n\r",numBytes);
        //pipedetails(pip);
        if (piptab[pip].pipstate == PIPE_CONNECTED) {
        while(numBytes < len){
                if((piptab[pip].nextpos == 0) && (nonempty(semtab[piptab[pip].supply].squeue)))
                {
                     //kprintf("reader is waiting until writer writes into the buffer\n\r");
                     wrflag = 1;
                }
                int remSpace = PIPE_SIZE - piptab[pip].nextpos;
                int toWrite = len - numBytes;
                int top = piptab[pip].nextpos;
                //kprintf("remSpace :%d, top(nxtpos) :%d ,toWrite :%d\n\r",remSpace,top,toWrite);
                if(toWrite > remSpace) {
                     for(i=top-1;i>=0;i--) {
                         piptab[pip].buffer[i + remSpace] = piptab[pip].buffer[i];
                     }
                     piptab[pip].nextpos = piptab[pip].nextpos + remSpace;
                     for(i=remSpace-1,j=numBytes;i>=0;i--,j++) {
                         (piptab[pip]).buffer[i] = buf[j];
                         numBytes++;
                     }
                //pipedetails(pip);
 	        if(wrflag == 1)
	        {
		     signal(piptab[pip].supply); 
                     wrflag = 0;
	        }
                //pipread could read some data if it gets scheduled after signal
                if(piptab[pip].nextpos == PIPE_SIZE) {
                     wait(piptab[pip].demand); 
                }
                else 
                {    
                  remSpace = PIPE_SIZE - piptab[pip].nextpos; 
                  if((piptab[pip].nextpos == 0) && (nonempty(semtab[piptab[pip].supply].squeue)))
	          {
	             //kprintf("writer is ..waiting until reader reads from the buffer\n\r");
          	     wrflag = 1;
	          }
                }
                //kprintf("back to pipwrite::numBytes : %d\n\r",numBytes);
                }    
                if(toWrite <= remSpace) {
                     //kprintf("toWrite (%d) < remSpace (%d)\n\r",toWrite,remSpace);
                     for(i=piptab[pip].nextpos-1;i>=0;i--) {
                         piptab[pip].buffer[i + toWrite] = piptab[pip].buffer[i];
                         //kprintf("[wr] buf[%d] :%c ,pipebuffer :%c  \t",i+toWrite,buf[i],piptab[pip].buffer[i]);
                     }
                     piptab[pip].nextpos = piptab[pip].nextpos + toWrite;
                     for(i=toWrite-1,j=numBytes;i>=0;i--,j++) {
                         piptab[pip].buffer[i] = buf[j];
                         //kprintf("[wr] buf[%d] :%c ,pipebuffer :%c , numBytes: %d \t",i,buf[i],piptab[pip].buffer[i],numBytes);
                         numBytes++;
                     }
                //pipedetails(pip); 
                }
                
        }
 	if(wrflag == 1)
	{
                //kprintf("[outside while] reader is waiting until writer writes into the buffer\n\r");
		signal(piptab[pip].supply);
	}
	restore(mask);
	return numBytes;
        }
        if (piptab[pip].pipstate == PIPE_DISCONNECTED) {
                piptab[pip].pipstate = PIPE_USED;
                piptab[pip].wrtend = -1;
                piptab[pip].nextpos = 0;
                restore(mask);
	        return SYSERR;
        }
        else {
                restore(mask);
	        return SYSERR;
        }
}