Esempio n. 1
0
static int32
InterruptHandler(void* data)
{
	int32 handled = B_UNHANDLED_INTERRUPT;
	DeviceInfo& di = *((DeviceInfo*)data);
	int32* flags = &(di.flags);

	// Is someone already handling an interrupt for this device?
	if (atomic_or(flags, SKD_HANDLER_INSTALLED) & SKD_HANDLER_INSTALLED)
		return B_UNHANDLED_INTERRUPT;

	if (InterruptIsVBI()) {	// was interrupt a VBI?
		ClearVBI();			// clear interrupt

		handled = B_HANDLED_INTERRUPT;

		// Release vertical blanking semaphore.
		sem_id& sem = di.sharedInfo->vertBlankSem;

		if (sem >= 0) {
			int32 blocked;
			if ((get_sem_count(sem, &blocked) == B_OK) && (blocked < 0)) {
				release_sem_etc(sem, -blocked, B_DO_NOT_RESCHEDULE);
				handled = B_INVOKE_SCHEDULER;
			}
		}
	}

	atomic_and(flags, ~SKD_HANDLER_INSTALLED);	// note we're not in handler anymore

	return handled;
}
Esempio n. 2
0
/*
 * How many waiting for input?
 */
static long
input_count(etherpci_private_t *data)
{
	long count;

	get_sem_count(data->ilock, &count);
	return (count);
}
Esempio n. 3
0
/*
 * How many waiting for input?
 */
static int32
input_count(etherpci_private_t *data)
{
	int32 count;

	get_sem_count(data->ilock, &count);
	return (count);
}
Esempio n. 4
0
long
setEvent(sem_id event)
{
	int32 c;
	get_sem_count(event,&c);
	if (c < 0)
	  release_sem_etc(event,-c,0);

	return 0;
}
Esempio n. 5
0
bool TSem::print_info() {

	int nsems = get_sem_total_count();
	printf("************* sem info *************\n");
	printf("pid : %d\n",semctl( m_semid,0,GETPID ));
	for ( int i = 0; i < nsems; i++ )
		printf("semval[%d] : %d\n",i,get_sem_count(i));
	printf("************************************\n");
	return true;
}
Esempio n. 6
0
void Semaphore::Wait()
{
	status_t	err;
#if SEM_DEBUG
	int32		tc;
	get_sem_count( mutex, &tc );
	PRINT(( "Semaphore::Wait:id(%d):count(%d)\n", mutex, tc ));
#endif
	if ( ( err = acquire_sem( mutex ) ) < B_NO_ERROR )
	{
		puts( "Sem::Wait:couldn't acquire sem" );
		DEBUGGER(( "Semaphore::Wait: couldn't acquire sem : %s\n",
					strerror( err ) ));
	}
#if SEM_DEBUG
	get_sem_count( mutex, &tc );
	PRINT(( "Semaphore::Wait:id(%d):count(%d) done\n", mutex, tc ));
#endif
}
Esempio n. 7
0
long
waitEvent(sem_id event)
{
	acquire_sem(event);

	int32 c;
	get_sem_count(event,&c);
	if (c > 0)
		acquire_sem_etc(event,c,0,0);

	return 0;
}
Esempio n. 8
0
File: sem2.c Progetto: code427/c
void show_sem_usage(int sid)
{
        int cntr=0, maxsems, semval;

        maxsems = get_sem_count(sid);

        while(cntr < maxsems) {
                semval = semctl(sid, cntr, GETVAL, 0);
                printf("Semaphore #%d:  --> %d\n", cntr, semval);
                cntr++;
        }
}
Esempio n. 9
0
File: driver.c Progetto: DonCN/haiku
static uint32 thread_interrupt_work(int32 *flags, vuint32 *regs, shared_info *si) {
	uint32 handled = B_HANDLED_INTERRUPT;
	/* release the vblank semaphore */
	if (si->vblank >= 0) {
		int32 blocked;
		if ((get_sem_count(si->vblank, &blocked) == B_OK) && (blocked < 0)) {
			release_sem_etc(si->vblank, -blocked, B_DO_NOT_RESCHEDULE);
			handled = B_INVOKE_SCHEDULER;
		}
	}
	return handled;
}
Esempio n. 10
0
static int32
release_vblank_sem(intel_info &info)
{
    int32 count;
    if (get_sem_count(info.shared_info->vblank_sem, &count) == B_OK
            && count < 0) {
        release_sem_etc(info.shared_info->vblank_sem, -count,
                        B_DO_NOT_RESCHEDULE);
        return B_INVOKE_SCHEDULER;
    }

    return B_HANDLED_INTERRUPT;
}
Esempio n. 11
0
static inline void
cx23882_mpegts_int(cx23882_device *device)
{
	uint32 mstat = reg_read32(REG_TS_INT_MSTAT);
	reg_write32(REG_TS_INT_STAT, mstat);
	
//	dprintf("cx23882_mpegts_int got 0x%08lx\n", mstat);

	if (mstat & TS_INT_STAT_OPC_ERR) {
		dprintf("cx23882_mpegts_int RISC opcode error\n");
		reg_write32(REG_PCI_INT_MSK, 0);
		return;
	}

	if ((mstat & (TS_INT_STAT_TS_RISC1 | TS_INT_STAT_TS_RISC2)) == (TS_INT_STAT_TS_RISC1 | TS_INT_STAT_TS_RISC2)) {
		dprintf("cx23882_mpegts_int both buffers ready\n");
		mstat = TS_INT_STAT_TS_RISC1;
	}
	
	if (mstat & TS_INT_STAT_TS_RISC1) {
		int32 count;
//		dprintf("cx23882_mpegts_int buffer 1 at %Ld\n", system_time());
		device->capture_data = device->dma_buf1_virt;
		device->capture_end_time = system_time();
		get_sem_count(device->capture_sem, &count);
		if (count <= 0)
			release_sem_etc(device->capture_sem, 1, B_DO_NOT_RESCHEDULE);
	}

	if (mstat & TS_INT_STAT_TS_RISC2) {
		int32 count;
//		dprintf("cx23882_mpegts_int buffer 2 at %Ld\n", system_time());
		device->capture_data = device->dma_buf2_virt;
		device->capture_end_time = system_time();
		get_sem_count(device->capture_sem, &count);
		if (count <= 0)
			release_sem_etc(device->capture_sem, 1, B_DO_NOT_RESCHEDULE);
	}
}
Esempio n. 12
0
/* Returns the current count of the semaphore */
Uint32 SDL_SemValue(SDL_sem *sem)
{
	int32 count;
	Uint32 value;

	value = 0;
	if ( sem ) {
		get_sem_count(sem->id, &count);
		if ( count > 0 ) {
			value = (Uint32)count;
		}
	}
	return value;
}
Esempio n. 13
0
status_t
_user_get_sem_count(sem_id id, int32 *userCount)
{
	status_t status;
	int32 count;

	if (userCount == NULL || !IS_USER_ADDRESS(userCount))
		return B_BAD_ADDRESS;

	status = get_sem_count(id, &count);
	if (status == B_OK && user_memcpy(userCount, &count, sizeof(int32)) < B_OK)
		return B_BAD_ADDRESS;

	return status;
}
Esempio n. 14
0
void
OHCI::_FinishTransfers()
{
	while (!fStopFinishThread) {
		if (acquire_sem(fFinishTransfersSem) < B_OK)
			continue;

		// eat up sems that have been released by multiple interrupts
		int32 semCount = 0;
		get_sem_count(fFinishTransfersSem, &semCount);
		if (semCount > 0)
			acquire_sem_etc(fFinishTransfersSem, semCount, B_RELATIVE_TIMEOUT, 0);

		if (!Lock())
			continue;

		TRACE("finishing transfers (first transfer: %p; last"
			" transfer: %p)\n", fFirstTransfer, fLastTransfer);
		transfer_data *lastTransfer = NULL;
		transfer_data *transfer = fFirstTransfer;
		Unlock();

		while (transfer) {
			bool transferDone = false;
			ohci_general_td *descriptor = transfer->first_descriptor;
			ohci_endpoint_descriptor *endpoint = transfer->endpoint;
			status_t callbackStatus = B_OK;

			MutexLocker endpointLocker(endpoint->lock);

			if ((endpoint->head_physical_descriptor & OHCI_ENDPOINT_HEAD_MASK)
				!= endpoint->tail_physical_descriptor) {
				// there are still active transfers on this endpoint, we need
				// to wait for all of them to complete, otherwise we'd read
				// a potentially bogus data toggle value below
				TRACE("endpoint %p still has active tds\n", endpoint);
				lastTransfer = transfer;
				transfer = transfer->link;
				continue;
			}

			endpointLocker.Unlock();

			while (descriptor && !transfer->canceled) {
				uint32 status = OHCI_TD_GET_CONDITION_CODE(descriptor->flags);
				if (status == OHCI_TD_CONDITION_NOT_ACCESSED) {
					// td is still active
					TRACE("td %p still active\n", descriptor);
					break;
				}

				if (status != OHCI_TD_CONDITION_NO_ERROR) {
					// an error occured, but we must ensure that the td
					// was actually done
					if (endpoint->head_physical_descriptor & OHCI_ENDPOINT_HALTED) {
						// the endpoint is halted, this guaratees us that this
						// descriptor has passed (we don't know if the endpoint
						// was halted because of this td, but we do not need
						// to know, as when it was halted by another td this
						// still ensures that this td was handled before).
						TRACE_ERROR("td error: 0x%08lx\n", status);

						switch (status) {
							case OHCI_TD_CONDITION_CRC_ERROR:
							case OHCI_TD_CONDITION_BIT_STUFFING:
							case OHCI_TD_CONDITION_TOGGLE_MISMATCH:
								callbackStatus = B_DEV_CRC_ERROR;
								break;

							case OHCI_TD_CONDITION_STALL:
								callbackStatus = B_DEV_STALLED;
								break;

							case OHCI_TD_CONDITION_NO_RESPONSE:
								callbackStatus = B_TIMED_OUT;
								break;

							case OHCI_TD_CONDITION_PID_CHECK_FAILURE:
								callbackStatus = B_DEV_BAD_PID;
								break;

							case OHCI_TD_CONDITION_UNEXPECTED_PID:
								callbackStatus = B_DEV_UNEXPECTED_PID;
								break;

							case OHCI_TD_CONDITION_DATA_OVERRUN:
								callbackStatus = B_DEV_DATA_OVERRUN;
								break;

							case OHCI_TD_CONDITION_DATA_UNDERRUN:
								callbackStatus = B_DEV_DATA_UNDERRUN;
								break;

							case OHCI_TD_CONDITION_BUFFER_OVERRUN:
								callbackStatus = B_DEV_FIFO_OVERRUN;
								break;

							case OHCI_TD_CONDITION_BUFFER_UNDERRUN:
								callbackStatus = B_DEV_FIFO_UNDERRUN;
								break;

							default:
								callbackStatus = B_ERROR;
								break;
						}

						transferDone = true;
						break;
					} else {
						// an error occured but the endpoint is not halted so
						// the td is in fact still active
						TRACE("td %p active with error\n", descriptor);
						break;
					}
				}

				// the td has completed without an error
				TRACE("td %p done\n", descriptor);

				if (descriptor == transfer->last_descriptor
					|| descriptor->buffer_physical != 0) {
					// this is the last td of the transfer or a short packet
					callbackStatus = B_OK;
					transferDone = true;
					break;
				}

				descriptor
					= (ohci_general_td *)descriptor->next_logical_descriptor;
			}

			if (transfer->canceled) {
				// when a transfer is canceled, all transfers to that endpoint
				// are canceled by setting the head pointer to the tail pointer
				// which causes all of the tds to become "free" (as they are
				// inaccessible and not accessed anymore (as setting the head
				// pointer required disabling the endpoint))
				callbackStatus = B_OK;
				transferDone = true;
			}

			if (!transferDone) {
				lastTransfer = transfer;
				transfer = transfer->link;
				continue;
			}

			// remove the transfer from the list first so we are sure
			// it doesn't get canceled while we still process it
			transfer_data *next = transfer->link;
			if (Lock()) {
				if (lastTransfer)
					lastTransfer->link = transfer->link;

				if (transfer == fFirstTransfer)
					fFirstTransfer = transfer->link;
				if (transfer == fLastTransfer)
					fLastTransfer = lastTransfer;

				// store the currently processing pipe here so we can wait
				// in cancel if we are processing something on the target pipe
				if (!transfer->canceled)
					fProcessingPipe = transfer->transfer->TransferPipe();

				transfer->link = NULL;
				Unlock();
			}

			// break the descriptor chain on the last descriptor
			transfer->last_descriptor->next_logical_descriptor = NULL;
			TRACE("transfer %p done with status 0x%08lx\n",
				transfer, callbackStatus);

			// if canceled the callback has already been called
			if (!transfer->canceled) {
				size_t actualLength = 0;
				if (callbackStatus == B_OK) {
					if (transfer->data_descriptor && transfer->incoming) {
						// data to read out
						iovec *vector = transfer->transfer->Vector();
						size_t vectorCount = transfer->transfer->VectorCount();

						transfer->transfer->PrepareKernelAccess();
						actualLength = _ReadDescriptorChain(
							transfer->data_descriptor,
							vector, vectorCount);
					} else if (transfer->data_descriptor) {
						// read the actual length that was sent
						actualLength = _ReadActualLength(
							transfer->data_descriptor);
					}

					// get the last data toggle and store it for next time
					transfer->transfer->TransferPipe()->SetDataToggle(
						(endpoint->head_physical_descriptor
							& OHCI_ENDPOINT_TOGGLE_CARRY) != 0);

					if (transfer->transfer->IsFragmented()) {
						// this transfer may still have data left
						TRACE("advancing fragmented transfer\n");
						transfer->transfer->AdvanceByFragment(actualLength);
						if (transfer->transfer->VectorLength() > 0) {
							TRACE("still %ld bytes left on transfer\n",
								transfer->transfer->VectorLength());
							// TODO actually resubmit the transfer
						}

						// the transfer is done, but we already set the
						// actualLength with AdvanceByFragment()
						actualLength = 0;
					}
				}

				transfer->transfer->Finished(callbackStatus, actualLength);
				fProcessingPipe = NULL;
			}

			if (callbackStatus != B_OK) {
				// remove the transfer and make the head pointer valid again
				// (including clearing the halt state)
				_RemoveTransferFromEndpoint(transfer);
			}

			// free the descriptors
			_FreeDescriptorChain(transfer->first_descriptor);

			delete transfer->transfer;
			delete transfer;
			transfer = next;
		}
	}
}
Esempio n. 15
0
fssh_status_t
fssh_get_sem_count(fssh_sem_id id, int32_t *threadCount)
{
	return get_sem_count(id, (int32*)threadCount);
}
Esempio n. 16
0
void FractalEngine::MessageReceived(BMessage* msg)
{
	switch (msg->what) {
	case MSG_CHANGE_SET:
		switch (msg->GetUInt8("set", 0)) {
		case 0: fDoSet = &FractalEngine::DoSet_Mandelbrot; break;
		case 1: fDoSet = &FractalEngine::DoSet_BurningShip; break;
		case 2: fDoSet = &FractalEngine::DoSet_Tricorn; break;
		case 3: fDoSet = &FractalEngine::DoSet_Julia; break;
		case 4: fDoSet = &FractalEngine::DoSet_OrbitTrap; break;
		case 5: fDoSet = &FractalEngine::DoSet_Multibrot; break;
		}
		break;
	case MSG_SET_PALETTE:
		switch (msg->GetUInt8("palette", 0)) {
		case 0: fColorset = Colorset_Royal; break;
		case 1: fColorset = Colorset_DeepFrost; break;
		case 2: fColorset = Colorset_Frost; break;
		case 3: fColorset = Colorset_Fire; break;
		case 4: fColorset = Colorset_Midnight; break;
		case 5: fColorset = Colorset_Grassland; break;
		case 6: fColorset = Colorset_Lightning; break;
		case 7: fColorset = Colorset_Spring; break;
		case 8: fColorset = Colorset_HighContrast; break;
		}
		break;
	case MSG_SET_ITERATIONS:
		fIterations = msg->GetUInt16("iterations", 0);
		break;
	case MSG_SET_SUBSAMPLING:
		fSubsampling = msg->GetUInt8("subsampling", 1);
		break;

	case MSG_RESIZE: {
		TRACE("Got MSG_RESIZE threads rendering\n");
		if (fStopRender) {
			// Will be true throughout this whole handler. Set false at the end
			TRACE("Breaking out of MSG_RESIZE handler\n");
			break;
		}
		StopRender();

		delete fRenderBuffer;
		fRenderBuffer = NULL;

		fWidth = msg->GetUInt16("width", 320);
		fHeight = msg->GetUInt16("height", 240);

		TRACE("Creating new buffer. width %u height %u\n", fWidth, fHeight);
		fRenderBufferLen = fWidth * fHeight * 3;
		fRenderBuffer = new uint8[fRenderBufferLen];
		memset(fRenderBuffer, 0, fRenderBufferLen);

		BMessage message(MSG_BUFFER_CREATED);
		fMessenger.SendMessage(&message);

		fStopRender = false;
		break;
	}
	case MSG_RENDER: {
		TRACE("Got MSG_RENDER.\n");
		StopRender();
		fStopRender = false;
		Render(msg->GetDouble("locationX", 0), msg->GetDouble("locationY", 0),
			msg->GetDouble("size", 0.005));
		break;
	}
	case MSG_THREAD_RENDER_COMPLETE: {
		TRACE("Got MSG_THREAD_RENDER_COMPLETE for thread %d\n",
			msg->GetUInt8("thread", 0));

		int32 threadsStopped;
		get_sem_count(fRenderStoppedSem, &threadsStopped);
		if (threadsStopped == fThreadCount) {
			TRACE("Done rendering!\n");
			BMessage message(MSG_RENDER_COMPLETE);
			fMessenger.SendMessage(&message);
		}
		break;
	}

	default:
		BLooper::MessageReceived(msg);
		break;
	}
}