static status_t my_transfer_data(my_device *device, bool directionIn, void *data, size_t dataLength) { status_t result = gUSBModule->queue_bulk(directionIn ? device->bulk_in : device->bulk_out, data, dataLength, my_callback, device); if (result != B_OK) { TRACE_ALWAYS("failed to queue data transfer\n"); return result; } do { bigtime_t timeout = directionIn ? 500000 : 500000; result = acquire_sem_etc(device->notify, 1, B_RELATIVE_TIMEOUT, timeout); if (result == B_TIMED_OUT) { // Cancel the transfer and collect the sem that should now be // released through the callback on cancel. Handling of device // reset is done in usb_printer_operation() when it detects that // the transfer failed. gUSBModule->cancel_queued_transfers(directionIn ? device->bulk_in : device->bulk_out); acquire_sem_etc(device->notify, 1, B_RELATIVE_TIMEOUT, 0); } } while (result == B_INTERRUPTED); if (result != B_OK) { TRACE_ALWAYS("acquire_sem failed while waiting for data transfer\n"); return result; } return B_OK; }
bool MultiLocker::WriteLock() { #if TIMING bigtime_t start = system_time(); #endif bool locked = false; if (fInit == B_OK) { uint32 stack_base = 0; thread_id thread = -1; if (IsWriteLocked(&stack_base, &thread)) { //already the writer - increment the nesting count fWriterNest++; locked = true; } else { //new writer acquiring the lock if (atomic_add(&fLockCount, 1) >= 1) { //another writer in the lock - acquire the semaphore locked = (acquire_sem_etc(fWriterLock, 1, B_DO_NOT_RESCHEDULE, B_INFINITE_TIMEOUT) == B_OK); } else locked = true; if (locked) { //new holder of the lock //decrement fReadCount by a very large number //this will cause new readers to block on fReadSem int32 readers = atomic_add(&fReadCount, -MAX_READERS); if (readers > 0) { //readers hold the lock - acquire fWriteSem locked = (acquire_sem_etc(fWriteSem, readers, B_DO_NOT_RESCHEDULE, B_INFINITE_TIMEOUT) == B_OK); } if (locked) { ASSERT(fWriterThread == -1); //record thread information fWriterThread = thread; fWriterStackBase = stack_base; } } } } #if TIMING bigtime_t end = system_time(); wl_time += (end - start); wl_count++; #endif return locked; }
status_t RemoteDrawingEngine::ReadBitmap(ServerBitmap* bitmap, bool drawCursor, BRect bounds) { if (_AddCallback() != B_OK) return B_UNSUPPORTED; RemoteMessage message(NULL, fHWInterface->SendBuffer()); message.Start(RP_READ_BITMAP); message.Add(fToken); message.Add(bounds); message.Add(drawCursor); if (message.Flush() != B_OK) return B_UNSUPPORTED; status_t result; do { result = acquire_sem_etc(fResultNotify, 1, B_RELATIVE_TIMEOUT, 100 * 1000 * 1000); } while (result == B_INTERRUPTED); if (result != B_OK) return result; BBitmap* read = fReadBitmapResult; if (read == NULL) return B_UNSUPPORTED; result = bitmap->ImportBits(read->Bits(), read->BitsLength(), read->BytesPerRow(), read->ColorSpace()); delete read; return result; }
BPoint RemoteDrawingEngine::DrawString(const char* string, int32 length, const BPoint* offsets) { // Guaranteed to have at least one point. RemoteMessage message(NULL, fHWInterface->SendBuffer()); message.Start(RP_DRAW_STRING_WITH_OFFSETS); message.Add(fToken); message.AddString(string, length); message.AddList(offsets, UTF8CountChars(string, length)); status_t result = _AddCallback(); if (message.Flush() != B_OK) return offsets[0]; if (result != B_OK) return offsets[0]; do { result = acquire_sem_etc(fResultNotify, 1, B_RELATIVE_TIMEOUT, 1 * 1000 * 1000); } while (result == B_INTERRUPTED); if (result != B_OK) return offsets[0]; return fDrawStringResult; }
BPoint RemoteDrawingEngine::DrawString(const char* string, int32 length, const BPoint& point, escapement_delta* delta) { RemoteMessage message(NULL, fHWInterface->SendBuffer()); message.Start(RP_DRAW_STRING); message.Add(fToken); message.Add(point); message.AddString(string, length); message.Add(delta != NULL); if (delta != NULL) message.AddList(delta, length); status_t result = _AddCallback(); if (message.Flush() != B_OK) return point; if (result != B_OK) return point; do { result = acquire_sem_etc(fResultNotify, 1, B_RELATIVE_TIMEOUT, 1 * 1000 * 1000); } while (result == B_INTERRUPTED); if (result != B_OK) return point; return fDrawStringResult; }
static status_t low_resource_manager(void*) { bigtime_t timeout = kLowResourceInterval; while (true) { int32 state = low_resource_state_no_update(B_ALL_KERNEL_RESOURCES); if (state != B_LOW_RESOURCE_CRITICAL) { acquire_sem_etc(sLowResourceWaitSem, 1, B_RELATIVE_TIMEOUT, timeout); } RecursiveLocker _(&sLowResourceLock); compute_state(); state = low_resource_state_no_update(B_ALL_KERNEL_RESOURCES); TRACE(("low_resource_manager: state = %ld, %ld free pages, %lld free " "memory, %lu free semaphores\n", state, vm_page_num_free_pages(), vm_available_not_needed_memory(), sem_max_sems() - sem_used_sems())); if (state < B_LOW_RESOURCE_NOTE) continue; call_handlers(sLowResources); if (state == B_LOW_RESOURCE_WARNING) timeout = kWarnResourceInterval; else timeout = kLowResourceInterval; sLowResourceWaiterCondition.NotifyAll(); } return 0; }
static status_t read_keyboard_packet(at_kbd_io *packet) { status_t status; TRACE("ps2: read_keyboard_packet: enter\n"); status = acquire_sem_etc(sKeyboardSem, 1, B_CAN_INTERRUPT, 0); if (status < B_OK) return status; if (!ps2_device[PS2_DEVICE_KEYB].active) { TRACE("ps2: read_keyboard_packet, Error device no longer active\n"); return B_ERROR; } if (packet_buffer_read(sKeyBuffer, (uint8 *)packet, sizeof(*packet)) == 0) { TRACE("ps2: read_keyboard_packet, Error reading packet: %s\n", strerror(status)); return B_ERROR; } TRACE("ps2: read_keyboard_packet: scancode: %x, keydown: %s\n", packet->scancode, packet->is_keydown ? "true" : "false"); return B_OK; }
void wait_for_vblank(void) { acquire_sem_etc(gInfo->shared_info->vblank_sem, 1, B_RELATIVE_TIMEOUT, 25000); // With the output turned off via DPMS, we might not get any interrupts anymore // that's why we don't wait forever for it. }
/* ---------- acpi_namespace_read - handle read() calls ----- */ static status_t acpi_namespace_read(void *_cookie, off_t position, void *buf, size_t* num_bytes) { acpi_ns_device_info *device = (acpi_ns_device_info *)_cookie; RingBuffer &ringBuffer = *device->buffer; if (!ringBuffer.Lock()) { *num_bytes = 0; return B_ERROR; } if (ringBuffer.ReadableAmount() == 0) { ringBuffer.Unlock(); status_t status = acquire_sem_etc(device->read_sem, 1, B_CAN_INTERRUPT, 0); if (status != B_OK && status != B_BAD_SEM_ID) { *num_bytes = 0; return status; } if (!ringBuffer.Lock()) { *num_bytes = 0; return B_ERROR; } } *num_bytes = ringBuffer.Read(buf, *num_bytes); ringBuffer.Unlock(); return B_OK; }
status_t UnixEndpoint::Accept(net_socket **_acceptedSocket) { TRACE("[%ld] %p->UnixEndpoint::Accept()\n", find_thread(NULL), this); bigtime_t timeout = absolute_timeout(socket->receive.timeout); if (gStackModule->is_restarted_syscall()) timeout = gStackModule->restore_syscall_restart_timeout(); else gStackModule->store_syscall_restart_timeout(timeout); UnixEndpointLocker locker(this); status_t error; do { locker.Unlock(); error = acquire_sem_etc(fAcceptSemaphore, 1, B_ABSOLUTE_TIMEOUT | B_CAN_INTERRUPT, timeout); if (error < B_OK) RETURN_ERROR(error); locker.Lock(); error = gSocketModule->dequeue_connected(socket, _acceptedSocket); } while (error != B_OK); if (error == B_TIMED_OUT && timeout == 0) { // translate non-blocking timeouts to the correct error code error = B_WOULD_BLOCK; } RETURN_ERROR(error); }
status_t Device::_MultiBufferExchange(multi_buffer_info* Info) { for (int i = 0; i < fStreams.Count(); i++) { if (!fStreams[i]->IsRunning()) { fStreams[i]->Start(); } } TRACE_ALWAYS("Exchange!\n"); snooze(1000000); return B_OK; status_t status = B_ERROR; bool anyBufferProcessed = false; for (int i = 0; i < fStreams.Count() && !anyBufferProcessed; i++) { status = acquire_sem_etc(fBuffersReadySem, 1, B_RELATIVE_TIMEOUT | B_CAN_INTERRUPT, 50000); if (status == B_TIMED_OUT) { TRACE_ALWAYS("Timeout during buffers exchange.\n"); break; } anyBufferProcessed = fStreams[i]->ExchangeBuffer(Info); status = anyBufferProcessed ? B_OK : B_ERROR; } return status; }
status_t BBufferGroup::ReclaimAllBuffers() { CALLED(); if (fInitError != B_OK) return B_NO_INIT; // because additional BBuffers might get added to this group betweeen // acquire and release int32 count = fBufferCount; if (count < 0) return B_BAD_VALUE; if (count == 0) return B_OK; // we need to wait until all BBuffers belonging to this group are reclaimed. // this has happened when the "fReclaimSem" can be aquired "fBufferCount" // times status_t status; do { status = acquire_sem_etc(fReclaimSem, count, 0, 0); } while (status == B_INTERRUPTED); if (status != B_OK) return status; // we need to release the "fReclaimSem" now, else we would block // requesting of new buffers return release_sem_etc(fReclaimSem, count, 0); }
// copy from graphics memory to other memory via DMA // src - offset in graphics mem // target - target address // size - number of bytes to copy // lock_mem - true, if memory is not locked // contiguous - true, if memory is physically contiguous (implies lock_mem=false) status_t Radeon_DMACopy( device_info *di, uint32 src, char *target, size_t size, bool lock_mem, bool contiguous ) { status_t res; /*SHOW_FLOW( 0, "src=%ld, target=%p, size=%ld, lock_mem=%d, contiguous=%d", src, target, size, lock_mem, contiguous );*/ res = Radeon_PrepareDMA( di, src, target, size, lock_mem, contiguous ); if( res != B_OK ) return res; //SHOW_FLOW0( 0, "2" ); OUTREG( di->regs, RADEON_DMA_VID_TABLE_ADDR, di->si->memory[mt_local].virtual_addr_start + di->dma_desc_offset ); res = acquire_sem_etc( di->dma_sem, 1, B_RELATIVE_TIMEOUT, 1000000 ); // be sure that transmission is really finished while( (INREG( di->regs, RADEON_DMA_VID_STATUS ) & RADEON_DMA_STATUS_ACTIVE) != 0 ) { SHOW_FLOW0( 0, "DMA transmission still active" ); snooze( 1000 ); } Radeon_FinishDMA( di, src, target, size, lock_mem, contiguous ); //SHOW_FLOW0( 0, "3" ); return res; }
void ProducerNode::BufferProducer() { // this thread produces one buffer each two seconds, // and shedules it to be handled one second later than produced // assuming a realtime timesource status_t rv; for (;;) { rv = acquire_sem_etc(mBufferProducerSem,1,B_RELATIVE_TIMEOUT,DELAY); if (rv == B_INTERRUPTED) { continue; } else if (rv == B_OK) { // triggered by AdditionalBufferRequested release_sem(mBufferProducerSem); } else if (rv != B_TIMED_OUT) { // triggered by deleting the semaphore (stop request) break; } if (!mOutputEnabled) continue; BBuffer *buffer; // out("ProducerNode: RequestBuffer\n"); buffer = mBufferGroup->RequestBuffer(2048); if (!buffer) { } buffer->Header()->start_time = TimeSource()->Now() + DELAY / 2; out("ProducerNode: SendBuffer, sheduled time = %5.4f\n",buffer->Header()->start_time / 1E6); rv = SendBuffer(buffer, mOutput.destination); if (rv != B_OK) { } } }
int32 BBlockFIFO::BeginPut(void **outData, size_t requestSize, bigtime_t timeout) { if (!outData) { FPRINTF(stderr, "BAD_VALUE: outData == NULL\n"); return B_BAD_VALUE; } if (_mFlags & flagEndOfData) { FPRINTF(stderr, "EPERM: end of data\n"); return EPERM; } ENTER_GET if (requestSize > _mBufferSize) { requestSize = _mBufferSize; } ssize_t o = _mPutOff + requestSize; if (o > (ssize_t)_mAreaSize) { o = _mAreaSize; } int32 req = o-_mPutOff; status_t err = acquire_sem_etc(_mPutSem, req, B_TIMEOUT, timeout); if (err < B_OK) { LEAVE_PUT FPRINTF(stderr, "BeginPut: acquire_sem_etc() returns %ld (req is %ld)\n", err, req); return err; } *outData = _mBuffer + _mPutOff; if (o == (ssize_t)_mAreaSize) _mPendingPut = 0; else _mPendingPut = o; atomic_or(&_mFlags, flagPendingPut); return req; }
void ActivityView::_Refresh() { bigtime_t lastTimeout = system_time() - RefreshInterval(); BMessenger target(this); while (true) { status_t status = acquire_sem_etc(fRefreshSem, 1, B_ABSOLUTE_TIMEOUT, lastTimeout + RefreshInterval()); if (status == B_OK || status == B_BAD_SEM_ID) break; if (status == B_INTERRUPTED) continue; SystemInfo info(fSystemInfoHandler); lastTimeout += RefreshInterval(); fSourcesLock.Lock(); for (uint32 i = fSources.CountItems(); i-- > 0;) { DataSource* source = fSources.ItemAt(i); DataHistory* values = fValues.ItemAt(i); int64 value = source->NextValue(info); values->AddValue(info.Time(), value); } fSourcesLock.Unlock(); target.SendMessage(B_INVALIDATE); } }
static status_t ethernet_link_checker(void *) { while (true) { status_t status = acquire_sem_etc(sLinkChangeSemaphore, 1, B_RELATIVE_TIMEOUT, kLinkCheckInterval); if (status == B_BAD_SEM_ID) break; MutexLocker _(sListLock); if (sCheckList.IsEmpty()) break; // check link state of all existing devices DoublyLinkedList<ethernet_device>::Iterator iterator = sCheckList.GetIterator(); while (iterator.HasNext()) { update_link_state(iterator.Next()); } } return B_OK; }
/*! The BigBrother thread send ping messages to the BMediaRoster of all currently running teams. If the reply times out or is wrong, the team cleanup function _TeamDied() will be called. */ void AppManager::_BigBrother() { status_t status = B_TIMED_OUT; BMessage ping('PING'); BMessage reply; do { if (!Lock()) break; bool startOver = false; AppMap::iterator iterator = fMap.begin(); for (; iterator != fMap.end(); iterator++) { reply.what = 0; status = iterator->second.SendMessage(&ping, &reply, 5000000, 2000000); if (status != B_OK || reply.what != 'PONG') { team_id team = iterator->first; Unlock(); _TeamDied(team); startOver = true; break; } } if (startOver) continue; Unlock(); status = acquire_sem_etc(fQuit, 1, B_RELATIVE_TIMEOUT, 2000000); } while (status == B_TIMED_OUT || status == B_INTERRUPTED); }
status_t DavicomDevice::Write(const uint8 *buffer, size_t *numBytes) { size_t numBytesToWrite = *numBytes; *numBytes = 0; if (fRemoved) { TRACE_ALWAYS("Error of writing %d bytes to removed device.\n", numBytesToWrite); return B_ERROR; } if (!fHasConnection) { TRACE_ALWAYS("Error of writing %d bytes to device while down.\n", numBytesToWrite); return B_ERROR; } if (fTXBufferFull) { TRACE_ALWAYS("Error of writing %d bytes to device while TX buffer full.\n", numBytesToWrite); return B_ERROR; } TRACE_FLOW("Write %d bytes.\n", numBytesToWrite); uint8 header[kTXHeaderSize]; header[0] = *numBytes & 0xFF; header[1] = *numBytes >> 8; iovec txData[] = { { &header, kTXHeaderSize }, { (uint8*)buffer, numBytesToWrite } }; status_t result = gUSBModule->queue_bulk_v(fWriteEndpoint, txData, 2, _WriteCallback, this); if (result != B_OK) { TRACE_ALWAYS("Error of queue_bulk_v request:%#010x\n", result); return result; } result = acquire_sem_etc(fNotifyWriteSem, 1, B_CAN_INTERRUPT, 0); if (result < B_OK) { TRACE_ALWAYS("Error of acquiring notify semaphore:%#010x.\n", result); return result; } if (fStatusWrite != B_OK && fStatusWrite != B_CANCELED && !fRemoved) { TRACE_ALWAYS("Device status error:%#010x\n", fStatusWrite); return fStatusWrite; } *numBytes = fActualLengthWrite - kTXHeaderSize;; TRACE_FLOW("Written %d bytes.\n", *numBytes); return B_OK; }
static status_t b57_read(void *cookie,off_t pos,void *data,size_t *numBytes) { struct be_b57_dev *pUmDevice = (struct be_b57_dev *)cookie; PLM_DEVICE_BLOCK pDevice = (PLM_DEVICE_BLOCK) pUmDevice; PLM_PACKET pPacket; struct B_UM_PACKET *pUmPacket; cpu_status cpu; if (pUmDevice->block) acquire_sem(pUmDevice->packet_release_sem); else { /* Decrement the receive sem anyway, but don't block this is a horrible hack, but it works. */ acquire_sem_etc(pUmDevice->packet_release_sem, 1, B_RELATIVE_TIMEOUT, 0); } cpu = disable_interrupts(); acquire_spinlock(&pUmDevice->lock); pPacket = (PLM_PACKET) QQ_PopHead(&pUmDevice->RxPacketReadQ.Container); release_spinlock(&pUmDevice->lock); restore_interrupts(cpu); if (pPacket == 0) { *numBytes = -1; return B_ERROR; } pUmPacket = (struct B_UM_PACKET *) pPacket; if (pPacket->PacketStatus != LM_STATUS_SUCCESS || pPacket->PacketSize > 1518) { cpu = disable_interrupts(); acquire_spinlock(&pUmDevice->lock); QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket); release_spinlock(&pUmDevice->lock); restore_interrupts(cpu); *numBytes = -1; return B_ERROR; } if ((pPacket->PacketSize) < *numBytes) *numBytes = pPacket->PacketSize; memcpy(data,pUmPacket->data,*numBytes); cpu = disable_interrupts(); acquire_spinlock(&pUmDevice->lock); QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket); release_spinlock(&pUmDevice->lock); restore_interrupts(cpu); return B_OK; }
PR_WaitCondVar (PRCondVar *cvar, PRIntervalTime timeout) { status_t err; if( timeout == PR_INTERVAL_NO_WAIT ) { PR_Unlock( cvar->lock ); PR_Lock( cvar->lock ); return PR_SUCCESS; } if( _MD_ATOMIC_INCREMENT( &cvar->signalBenCount ) > 1 ) { if (acquire_sem(cvar->signalSem) == B_INTERRUPTED) { _MD_ATOMIC_DECREMENT( &cvar->signalBenCount ); return PR_FAILURE; } } cvar->nw += 1; if( _MD_ATOMIC_DECREMENT( &cvar->signalBenCount ) > 0 ) { release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE); } PR_Unlock( cvar->lock ); if( timeout==PR_INTERVAL_NO_TIMEOUT ) { err = acquire_sem(cvar->sem); } else { err = acquire_sem_etc(cvar->sem, 1, B_RELATIVE_TIMEOUT, PR_IntervalToMicroseconds(timeout) ); } if( _MD_ATOMIC_INCREMENT( &cvar->signalBenCount ) > 1 ) { while (acquire_sem(cvar->signalSem) == B_INTERRUPTED); } if (cvar->ns > 0) { release_sem_etc(cvar->handshakeSem, 1, B_DO_NOT_RESCHEDULE); cvar->ns -= 1; } cvar->nw -= 1; if( _MD_ATOMIC_DECREMENT( &cvar->signalBenCount ) > 0 ) { release_sem_etc(cvar->signalSem, 1, B_DO_NOT_RESCHEDULE); } PR_Lock( cvar->lock ); if(err==B_NO_ERROR || (err == B_TIMED_OUT && timeout!=PR_INTERVAL_NO_TIMEOUT)) { return PR_SUCCESS; } return PR_FAILURE; }
void condition_variable::wait_for(mutex::scoped_lock& l, time_duration rel_time) { TORRENT_ASSERT(l.locked()); ++m_num_waiters; l.unlock(); acquire_sem_etc(m_sem, 1, B_RELATIVE_TIMEOUT, total_microseconds(rel_time)); l.lock(); --m_num_waiters; }
status_t ice1712_buffer_exchange(ice1712 *card, multi_buffer_info *data) { int cpu_status; multi_buffer_info buffer_info; #ifdef __HAIKU__ if (user_memcpy(&buffer_info, data, sizeof(buffer_info)) < B_OK) return B_BAD_ADDRESS; #else memcpy(&buffer_info, data, sizeof(buffer_info)); #endif buffer_info.flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD; if (acquire_sem_etc(card->buffer_ready_sem, 1, B_RELATIVE_TIMEOUT | B_CAN_INTERRUPT, 50000) == B_TIMED_OUT) { TRACE("buffer_exchange timeout\n"); }; cpu_status = lock(); // Playback buffers info buffer_info.played_real_time = card->played_time; buffer_info.played_frames_count = card->frames_count; buffer_info.playback_buffer_cycle = (card->buffer - 1) % SWAPPING_BUFFERS; //Buffer played // Record buffers info buffer_info.recorded_real_time = card->played_time; buffer_info.recorded_frames_count = card->frames_count; buffer_info.record_buffer_cycle = (card->buffer - 1) % SWAPPING_BUFFERS; //Buffer filled unlock(cpu_status); /* if ((card->buffer % 1500) == 0) { uint8 reg8, reg8_dir; reg8 = read_gpio(card); reg8_dir = read_cci_uint8(card, CCI_GPIO_DIRECTION_CONTROL); TRACE("DEBUG === GPIO = %d (dir %d)\n", reg8, reg8_dir); reg8 = spdif_read(card, CS84xx_VERSION_AND_CHIP_ID); TRACE("DEBUG === S/PDif Version : 0x%x\n", reg8); }*/ #ifdef __HAIKU__ if (user_memcpy(data, &buffer_info, sizeof(buffer_info)) < B_OK) return B_BAD_ADDRESS; #else memcpy(data, &buffer_info, sizeof(buffer_info)); #endif return B_OK; }
status_t ASIXDevice::Write(const uint8 *buffer, size_t *numBytes) { size_t numBytesToWrite = *numBytes; *numBytes = 0; if (fRemoved) { TRACE_ALWAYS("Error of writing %d bytes to removed device.\n", numBytesToWrite); return B_DEVICE_NOT_FOUND; } TRACE_FLOW("Write %d bytes.\n", numBytesToWrite); TRXHeader header(numBytesToWrite); iovec txData[] = { { &header, sizeof(TRXHeader) }, { (uint8*)buffer, numBytesToWrite } }; size_t startIndex = fUseTRXHeader ? 0 : 1 ; size_t chunkCount = fUseTRXHeader ? 2 : 1 ; status_t result = gUSBModule->queue_bulk_v(fWriteEndpoint, &txData[startIndex], chunkCount, _WriteCallback, this); if (result != B_OK) { TRACE_ALWAYS("Error of queue_bulk_v request:%#010x\n", result); return result; } result = acquire_sem_etc(fNotifyWriteSem, 1, B_CAN_INTERRUPT, 0); if (result < B_OK) { TRACE_ALWAYS("Error of acquiring notify semaphore:%#010x.\n", result); return result; } if (fStatusWrite != B_OK && fStatusWrite != B_CANCELED && !fRemoved) { TRACE_ALWAYS("Device status error:%#010x\n", fStatusWrite); result = gUSBModule->clear_feature(fWriteEndpoint, USB_FEATURE_ENDPOINT_HALT); if (result != B_OK) { TRACE_ALWAYS("Error during clearing of HALT state:%#010x\n", result); return result; } } if (fUseTRXHeader) { *numBytes = fActualLengthWrite - sizeof(TRXHeader); } else { *numBytes = fActualLengthWrite; } TRACE_FLOW("Written %d bytes.\n", *numBytes); return B_OK; }
// _AcquireBenaphore status_t RWLocker::_AcquireBenaphore(Benaphore& benaphore, bigtime_t timeout) { status_t error = B_OK; if (atomic_add(&benaphore.counter, 1) > 0) { error = acquire_sem_etc(benaphore.semaphore, 1, B_ABSOLUTE_TIMEOUT, timeout); } return error; }
void Filter::Wait() { if (fStarted) { // wait for threads to exit while (acquire_sem_etc(fWaitForThreads, fN, 0, 0) == B_INTERRUPTED); // ready to start again fStarted = false; } }
void GlutBlocker::WaitEvent(bigtime_t usecs) { acquire_sem(gSem); if(!events) { // wait for new event sleeping = true; release_sem(gSem); acquire_sem_etc(eSem, 1, B_TIMEOUT, usecs); // wait for next event or timeout } else { release_sem(gSem); } }
status_t SerialDevice::_WriteToDevice() { char *buffer = fOutputBuffer; size_t bytesLeft = fOutputBufferSize; status_t status = gTTYModule->tty_read(fDeviceTTYCookie, buffer, &bytesLeft); if (status != B_OK) { TRACE_ALWAYS("write to device: failed to read from TTY: %s\n", strerror(status)); return status; } while (!fDeviceRemoved && bytesLeft > 0) { size_t length = MIN(bytesLeft, fWriteBufferSize); size_t packetLength = length; OnWrite(buffer, &length, &packetLength); status = gUSBModule->queue_bulk(fWritePipe, fWriteBuffer, packetLength, _WriteCallbackFunction, this); if (status != B_OK) { TRACE_ALWAYS("write to device: queueing failed with status " "0x%08x\n", status); return status; } status = acquire_sem_etc(fDoneWrite, 1, B_CAN_INTERRUPT, 0); if (status != B_OK) { TRACE_ALWAYS("write to device: failed to get write done sem " "0x%08x\n", status); return status; } if (fStatusWrite != B_OK) { TRACE("write to device: device status error 0x%08x\n", fStatusWrite); if (fStatusWrite == B_DEV_STALLED) { status = gUSBModule->clear_feature(fWritePipe, USB_FEATURE_ENDPOINT_HALT); if (status != B_OK) { TRACE_ALWAYS("write to device: failed to clear device " "halt\n"); return B_ERROR; } } continue; } buffer += length; bytesLeft -= length; } return B_OK; }
int32 SerialDevice::DeviceThread(void *data) { SerialDevice *device = (SerialDevice *)data; while (!device->fStopDeviceThread) { status_t status = gUSBModule->queue_bulk(device->fReadPipe, device->fReadBuffer, device->fReadBufferSize, device->ReadCallbackFunction, data); if (status < B_OK) { TRACE_ALWAYS("device thread: queueing failed with error: 0x%08x\n", status); break; } status = acquire_sem_etc(device->fDoneRead, 1, B_CAN_INTERRUPT, 0); if (status < B_OK) { TRACE_ALWAYS("device thread: failed to get read done sem 0x%08x\n", status); break; } if (device->fStatusRead != B_OK) { TRACE("device thread: device status error 0x%08x\n", device->fStatusRead); if (gUSBModule->clear_feature(device->fReadPipe, USB_FEATURE_ENDPOINT_HALT) != B_OK) { TRACE_ALWAYS("device thread: failed to clear halt feature\n"); break; } } char *buffer = device->fReadBuffer; size_t readLength = device->fActualLengthRead; device->OnRead(&buffer, &readLength); if (readLength == 0) continue; ddrover *ddr = gTTYModule->ddrstart(NULL); if (!ddr) { TRACE_ALWAYS("device thread: ddrstart problem\n"); return B_NO_MEMORY; } while (device->fInputStopped) snooze(100); gTTYModule->ttyilock(&device->fTTY, ddr, true); for (size_t i = 0; i < readLength; i++) gTTYModule->ttyin(&device->fTTY, ddr, buffer[i]); gTTYModule->ttyilock(&device->fTTY, ddr, false); gTTYModule->ddrdone(ddr); } return B_OK; }
status_t SerialDevice::Write(const char *buffer, size_t *numBytes) { size_t bytesLeft = *numBytes; *numBytes = 0; status_t status = mutex_lock(&fWriteLock); if (status != B_OK) { TRACE_ALWAYS("write: failed to get write lock\n"); return status; } if (fDeviceRemoved) { mutex_unlock(&fWriteLock); return B_DEV_NOT_READY; } while (bytesLeft > 0) { size_t length = MIN(bytesLeft, fWriteBufferSize); size_t packetLength = length; OnWrite(buffer, &length, &packetLength); status = gUSBModule->queue_bulk(fWritePipe, fWriteBuffer, packetLength, WriteCallbackFunction, this); if (status < B_OK) { TRACE_ALWAYS("write: queueing failed with status 0x%08x\n", status); break; } status = acquire_sem_etc(fDoneWrite, 1, B_CAN_INTERRUPT, 0); if (status < B_OK) { TRACE_ALWAYS("write: failed to get write done sem 0x%08x\n", status); break; } if (fStatusWrite != B_OK) { TRACE("write: device status error 0x%08x\n", fStatusWrite); status = gUSBModule->clear_feature(fWritePipe, USB_FEATURE_ENDPOINT_HALT); if (status < B_OK) { TRACE_ALWAYS("write: failed to clear device halt\n"); status = B_ERROR; break; } continue; } buffer += length; *numBytes += length; bytesLeft -= length; } mutex_unlock(&fWriteLock); return status; }