Esempio n. 1
0
intptr_t ConsoleDrv::Write(const void* buffer, size_t bufSize)
{
	const char* buf = (const char*)buffer;
	const char* bufEnd = buf + bufSize;
	SemaphoreDown(&conMutex);
	while (buf != bufEnd)
	{
		int c = *buf++;
		if (c == '\n')
			newline();
		else if (c == '\t')
		{
			m_conX = (m_conX&~7) + 8;
			if (m_conX >= m_conW)
				newline();
		} else
		{
			drawChar(m_conX++, m_conY, c);
			if (m_conX >= m_conW)
				newline();
		}
	}
	SemaphoreUp(&conMutex);
	return bufSize;
}
Esempio n. 2
0
u32 mailboxExecCmd(int channel, u32 value)
{
	channel &= MBCHN__MASK;
	value &= ~MBCHN__MASK;
	value |= channel;
	SemaphoreDown(&mbSem);
	CpuSyncBarrier();

	// Perform write operation
	while (REG_MBSTAT & MB_FULL);
	REG_MBWRITE = value;

	// Perform read operation
	for (;;)
	{
		while (REG_MBSTAT & MB_EMPTY);
		value = REG_MBREAD;
		if ((value & MBCHN__MASK) == channel)
		{
			value &= ~MBCHN__MASK;
			break;
		}
	}

	CpuSyncBarrier();
	SemaphoreUp(&mbSem);
	return value &~ MBCHN__MASK;
}
Esempio n. 3
0
COUNT PipeReadInner( char * buff, COUNT size, PIPE_READ pipe ) {
        BOOL wasFull;
        BOOL dataLeft;
        COUNT read;

        //Acquire EmptyLock - No readers can progress until there is data.
        SemaphoreDown( & pipe->EmptyLock, NULL );

        //Acqure mutex lock - No one can do any io until
        //we leave the buffer.
        SemaphoreDown( & pipe->Mutex, NULL );

        //Check and see if the buffer is full.
        //If it is, then the FullLock should
        //have been leaked, and writers should be blocking.
        wasFull = RingBufferIsFull( & pipe->Ring );
        ASSERT( wasFull ? (pipe->FullLock.Count == 0) : TRUE );

        //Perform the read.
        read = RingBufferRead( buff, size, & pipe->Ring );
        // Ring is protected by a read lock which should prevent zero length reads.
        ASSERT( read > 0 );

        //See if the ring buffer is empty.
        //If it is then we need to leak the reader lock.
        dataLeft = !RingBufferIsEmpty( & pipe->Ring );

        //Release mutex lock - We are out of the ring, so
        //let other IO go if its already passed.
        SemaphoreUp( & pipe->Mutex );

        //If the ring was full while we have exclusive access,
        //and we  freed up some space then we should release
        //the writer lock so writers can go.
        if( wasFull && read > 0 ) {
                SemaphoreUp( & pipe->FullLock );
        }

        //If there is data left in the buffer, release the
        //empty lock so that other readers can go.
        //If there is no data in the buffer, we cant let
        //readers progress, so we leak the lock.
        if( dataLeft ) {
                SemaphoreUp( & pipe->EmptyLock );
        }
        return read;
}
Esempio n. 4
0
COUNT PipeWriteInner( char * buff, COUNT size, PIPE_WRITE pipe ) {
        BOOL wasEmpty;
        BOOL spaceLeft;
        COUNT write;

        //Acquire FullLock - No writers can progress until we are done.
        SemaphoreDown( & pipe->FullLock, NULL );

        //Acqure mutex lock - No one can do any io until
        //we leave the buffer.
        SemaphoreDown( & pipe->Mutex, NULL );

        //Check and see if the buffer is empty.
        //If it is, then the EmptyLock should
        //have been leaked, and readers should be blocking.
        wasEmpty = RingBufferIsEmpty( & pipe->Ring );
        ASSERT( wasEmpty ? (pipe->EmptyLock.Count == 0) : TRUE );

        //Perform the write.
        write = RingBufferWrite( buff, size, & pipe->Ring );
        // Ring is protected by a write lock which should prevent zero length writes.
        ASSERT( write > 0 );

        //See if the ring buffer is empty.
        //If it is then we need to leak the reader lock.
        spaceLeft = !RingBufferIsFull( & pipe->Ring );

        //Release mutex lock - We are out of the ring, so
        //let other IO go if its already passed.
        SemaphoreUp( & pipe->Mutex );

        //If the ring was empty while we have exclusive access,
        //and we wrote some data, then we should release
        //the EmptyLock so readers can go.
        if( wasEmpty && write > 0 ) {
                SemaphoreUp( & pipe->EmptyLock );
        }

        //If there is space left in the buffer, release the
        //FullLock so that other writers can go.
        //If there is no space in the buffer, we cant let
        //writers progress, so we leak the lock.
        if( spaceLeft ) {
                SemaphoreUp( & pipe->FullLock );
        }
        return write;
}
Esempio n. 5
0
/*
 * Reads data from a pipe.
 *
 * Arguments:
 * buff - destination buffer
 * size - maximum length that will be read.
 * pipe - pipe we will read from
 *
 * Returns
 * The length of data we read.
 *
 * The size of the read data will be min( data in pipe, size)
 */
COUNT PipeRead( char * buff, COUNT size, PIPE_READ pipe )
{
        COUNT read;
        SemaphoreDown( & pipe->ReadLock, NULL );
        read = PipeReadInner(buff, size, pipe);
        SemaphoreUp( & pipe->ReadLock);
        return read;
}
Esempio n. 6
0
/*
 * Writes data to a pipe.
 *
 * Arguments
 * buff - buffer we will read from
 * size - the maximum distance we will read from.
 * pipe - the pipe we will copy data to.
 *
 * Returns
 * The length of data we read from buff.
 *
 * The size of the written data will be min( space left in pipe, size)
 */
COUNT PipeWrite( char * buff, COUNT size, PIPE_WRITE pipe )
{
        COUNT write;
        SemaphoreDown( & pipe->WriteLock, NULL );
        write = PipeWriteInner(buff, size, pipe);
        SemaphoreUp( & pipe->WriteLock);
        return write;
}
Esempio n. 7
0
void PipeReadStruct( char * buff, COUNT size, PIPE_READ pipe )
{
        COUNT read = 0;
        SemaphoreDown( & pipe->ReadLock, NULL );
        while (read < size) {
                read += PipeReadInner(buff+read, size-read, pipe);
        }
        SemaphoreUp( & pipe->ReadLock);
        ASSERT(read == size);
}
Esempio n. 8
0
void PipeWriteStruct( char * buff, COUNT size, PIPE_WRITE pipe )
{
        COUNT write = 0;
        SemaphoreDown( & pipe->WriteLock, NULL );
        while (write < size) {
                write += PipeWriteInner(buff+write, size-write, pipe);
        }
        SemaphoreUp( & pipe->WriteLock);
        ASSERT(write == size);
}
Esempio n. 9
0
/*
 * Adds a work item 'item' to the work queue 'queue'.
 * It is not safe to add work items to the queue which have already been
 * registered. Calling WorkerItemIsFinished() can solve this engima.
 */
void WorkerAddItem( struct WORKER_QUEUE * queue, struct WORKER_ITEM * item )
{

        //Make sure we are at thread level.
        ASSERT( !SoftInterruptIsAtomic() );

        SemaphoreUp( & queue->Lock );

        //We mark finished inside interrupt section so that WorkerItemIsFinished
        //returns accurate results.
        item->Queue = queue;

        CritInterruptDisable();
        //Finished needs to be updated with critical sections disabled.
        item->Finished = FALSE;
        //Adding to the queue needs to be done with Critinterrupts Disabled.
        LinkedListEnqueue( &item->Link.LinkedListLink, & queue->List );
        CritInterruptEnable();
}