void coalesceIfNecessary(buffer* aBuffer) { if (aBuffer->size == 8192) { removeBufferFromFreeList(aBuffer, getFreeList(aBuffer->size)); if (debug) printf("Coalesced to max size\n"); freeListPointers* freeLists = (freeListPointers*)entryPoint->ptr; pageHeaderInfo* pageHeader = (void*)aBuffer->start - sizeof(pageHeaderInfo); if (debug) printf("The start is at %p and the page header is at %p\n", aBuffer->start, pageHeader); free_page(pageHeader->pageInfo); freeLists->numAllocatedPages--; if (freeLists->numAllocatedPages == 0) { free_page(entryPoint); entryPoint = 0; } return; } buffer* buddy = getBuddy(aBuffer); if (debug) printf("Trying to coalesce a buffer of size %i\n", aBuffer->size); if (!buddy->isAllocated && buddy->size == aBuffer->size) { freeListInfo* freeList = getFreeList(buddy->size); removeBufferFromFreeList(buddy, freeList); removeBufferFromFreeList(aBuffer, freeList); buffer* parent = buddy < aBuffer ? buddy : aBuffer; parent->size = parent->size*2; addBufferToFreeList(parent, getFreeList(parent->size)); coalesceIfNecessary(parent); } }
/* * This is a helper method used to merge a block with it's buddy if both the blocks are * free to be merged into one */ void merge_memBlock(metadata_t* memBlock) { int freelist_index = log_Base_2(memBlock->size) - 4; //We are subtracting 4 because the smallest memory block size we have is 16 //which should correspond to index 0, so log 16 = 4 - 4 would give us 0 metadata_t* buddy = getBuddy(memBlock); //first defining the cases where we cannot merge if(memBlock->size >= SBRK_SIZE) { //if the block has a size more than or equal to 2048 //then we cannot merge it into anything bigger so we just place it along with //2048 blocks and do not merge anything add_freelist_top(memBlock, 7); return; } else if (buddy->in_use || (buddy->size != memBlock->size)) { //If the block's buddy is in use or if the block's size does not match with the buddy's size then //we do not merge them instead we just place the block at the correct index and return add_freelist_top(memBlock, freelist_index); return; } //Removing the ones we are merging from their original position in the free list while (buddy == freelist[freelist_index] || memBlock == freelist[freelist_index]) { if(buddy == freelist[freelist_index]) { remove_freelist_top(buddy, freelist_index); //buddy's next becomes NULL } if(memBlock == freelist[freelist_index]) { remove_freelist_top(memBlock, freelist_index); //block's next becomes NULL } } //removing the block and buddy from their position in the linked list remove_from_freelist(memBlock); remove_from_freelist(buddy); if(memBlock > buddy) { buddy->size = buddy->size*2; merge_memBlock(buddy); } else { memBlock->size = memBlock->size*2; merge_memBlock(memBlock); } }
void RosterManager::removeBuddy(const std::string &name) { Buddy *buddy = getBuddy(name); if (!buddy) { LOG4CXX_WARN(logger, m_user->getJID().toString() << ": Tried to remove unknown buddy " << name); return; } doRemoveBuddy(buddy); if (m_rosterStorage) m_rosterStorage->removeBuddy(buddy); unsetBuddy(buddy); delete buddy; }
void RosterManager::handleSubscription(Swift::Presence::ref presence) { std::string legacyName = Buddy::JIDToLegacyName(presence->getTo(), m_user); if (legacyName.empty()) { return; } // For server mode the subscription changes are handler in rosterresponder.cpp // using roster pushes. if (m_component->inServerMode()) { Swift::Presence::ref response = Swift::Presence::create(); response->setTo(presence->getFrom().toBare()); response->setFrom(presence->getTo().toBare()); Buddy *buddy = getBuddy(legacyName); if (buddy) { LOG4CXX_INFO(logger, m_user->getJID().toString() << ": Subscription received and buddy " << legacyName << " is already there => answering"); switch (presence->getType()) { case Swift::Presence::Subscribe: onBuddyAdded(buddy); response->setType(Swift::Presence::Subscribed); break; case Swift::Presence::Unsubscribe: onBuddyRemoved(buddy); removeBuddy(buddy->getName()); buddy = NULL; response->setType(Swift::Presence::Unsubscribed); break; case Swift::Presence::Subscribed: onBuddyAdded(buddy); break; default: return; } m_component->getFrontend()->sendPresence(response); } else { BuddyInfo buddyInfo; switch (presence->getType()) { // buddy is not in roster, so add him case Swift::Presence::Subscribe: buddyInfo.id = -1; buddyInfo.alias = ""; buddyInfo.legacyName = legacyName; buddyInfo.subscription = "both"; buddyInfo.flags = Buddy::buddyFlagsFromJID(presence->getTo()); LOG4CXX_INFO(logger, m_user->getJID().toString() << ": Subscription received for new buddy " << buddyInfo.legacyName << " => adding to legacy network"); buddy = m_component->getFactory()->createBuddy(this, buddyInfo); setBuddy(buddy); onBuddyAdded(buddy); response->setType(Swift::Presence::Subscribed); break; case Swift::Presence::Subscribed: // onBuddyAdded(buddy); return; // buddy is not there, so nothing to do, just answer case Swift::Presence::Unsubscribe: buddyInfo.id = -1; buddyInfo.alias = ""; buddyInfo.legacyName = legacyName; buddyInfo.subscription = "both"; buddyInfo.flags = Buddy::buddyFlagsFromJID(presence->getTo()); buddy = m_component->getFactory()->createBuddy(this, buddyInfo); onBuddyRemoved(buddy); delete buddy; response->setType(Swift::Presence::Unsubscribed); break; default: return; } m_component->getFrontend()->sendPresence(response); } } else { Swift::Presence::ref response = Swift::Presence::create(); Swift::Presence::ref currentPresence; response->setTo(presence->getFrom().toBare()); response->setFrom(presence->getTo().toBare()); Buddy *buddy = getBuddy(legacyName); if (buddy) { std::vector<Swift::Presence::ref> &presences = buddy->generatePresenceStanzas(255); switch (presence->getType()) { // buddy is already there, so nothing to do, just answer case Swift::Presence::Subscribe: onBuddyAdded(buddy); response->setType(Swift::Presence::Subscribed); BOOST_FOREACH(Swift::Presence::ref ¤tPresence, presences) { currentPresence->setTo(presence->getFrom()); m_component->getFrontend()->sendPresence(currentPresence); } if (buddy->getSubscription() != Buddy::Both) { buddy->setSubscription(Buddy::Both); storeBuddy(buddy); } break; // remove buddy case Swift::Presence::Unsubscribe: response->setType(Swift::Presence::Unsubscribed); onBuddyRemoved(buddy); removeBuddy(buddy->getName()); buddy = NULL; break; // just send response case Swift::Presence::Unsubscribed: response->setType(Swift::Presence::Unsubscribe); // We set both here, because this Unsubscribed can be response to // subscribe presence and we don't want that unsubscribe presence // to be send later again if (buddy->getSubscription() != Buddy::Both) { buddy->setSubscription(Buddy::Both); storeBuddy(buddy); } break; case Swift::Presence::Subscribed: if (buddy->getSubscription() != Buddy::Both) { buddy->setSubscription(Buddy::Both); storeBuddy(buddy); } return; default: return; } } else {