static void put_request_buffer(arp_entry* entry, net_buffer* buffer) { net_buffer* requestBuffer = atomic_pointer_test_and_set( &entry->request_buffer, buffer, (net_buffer*)NULL); if (requestBuffer != NULL) { // someone else took over ownership of the request buffer gBufferModule->free(buffer); } }
static net_buffer* get_request_buffer(arp_entry* entry) { net_buffer* buffer = entry->request_buffer; if (buffer == NULL || buffer == kDeletedBuffer) return NULL; buffer = atomic_pointer_test_and_set(&entry->request_buffer, (net_buffer*)NULL, buffer); if (buffer == kDeletedBuffer) return NULL; return buffer; }
// Record the sem_undo operation into our private fUndoList and // the team undo_list. The only limit here is the memory needed // for creating a new sem_undo structure. int RecordUndo(short semaphoreNumber, short value) { // Look if there is already a record from the team caller // for the same semaphore set bool notFound = true; Team *team = thread_get_current_thread()->team; DoublyLinkedList<sem_undo>::Iterator iterator = fUndoList.GetIterator(); while (iterator.HasNext()) { struct sem_undo *current = iterator.Next(); if (current->team == team) { // Update its undo value MutexLocker _(team->xsi_sem_context->lock); int newValue = current->undo_values[semaphoreNumber] + value; if (newValue > USHRT_MAX || newValue < -USHRT_MAX) { TRACE_ERROR(("XsiSemaphoreSet::RecordUndo: newValue %d " "out of range\n", newValue)); return ERANGE; } current->undo_values[semaphoreNumber] = newValue; notFound = false; TRACE(("XsiSemaphoreSet::RecordUndo: found record. Team = %d, " "semaphoreSetID = %d, semaphoreNumber = %d, value = %d\n", (int)team->id, fID, semaphoreNumber, current->undo_values[semaphoreNumber])); break; } } if (notFound) { // First sem_undo request from this team for this // semaphore set int16 *undoValues = (int16 *)malloc(sizeof(int16) * fNumberOfSemaphores); if (undoValues == NULL) return B_NO_MEMORY; struct sem_undo *request = new(std::nothrow) sem_undo(this, team, undoValues); if (request == NULL) { free(undoValues); return B_NO_MEMORY; } memset(request->undo_values, 0, sizeof(int16) * fNumberOfSemaphores); request->undo_values[semaphoreNumber] = value; // Check if it's the very first sem_undo request for this team xsi_sem_context *context = atomic_pointer_get(&team->xsi_sem_context); if (context == NULL) { // Create the context context = new(std::nothrow) xsi_sem_context; if (context == NULL) { free(request->undo_values); delete request; return B_NO_MEMORY; } // Since we don't hold any global lock, someone // else could have been quicker than us, so we have // to delete the one we just created and use the one // in place. if (atomic_pointer_test_and_set(&team->xsi_sem_context, context, (xsi_sem_context *)NULL) != NULL) delete context; } // Add the request to both XsiSemaphoreSet and team list fUndoList.Add(request); MutexLocker _(team->xsi_sem_context->lock); team->xsi_sem_context->undo_list.Add(request); TRACE(("XsiSemaphoreSet::RecordUndo: new record added. Team = %d, " "semaphoreSetID = %d, semaphoreNumber = %d, value = %d\n", (int)team->id, fID, semaphoreNumber, value)); } return B_OK; }