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; }
/* * How many waiting for input? */ static long input_count(etherpci_private_t *data) { long count; get_sem_count(data->ilock, &count); return (count); }
/* * How many waiting for input? */ static int32 input_count(etherpci_private_t *data) { int32 count; get_sem_count(data->ilock, &count); return (count); }
long setEvent(sem_id event) { int32 c; get_sem_count(event,&c); if (c < 0) release_sem_etc(event,-c,0); return 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; }
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 }
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; }
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++; } }
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; }
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; }
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); } }
/* 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; }
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; }
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; } } }
fssh_status_t fssh_get_sem_count(fssh_sem_id id, int32_t *threadCount) { return get_sem_count(id, (int32*)threadCount); }
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; } }