Ejemplo n.º 1
0
/* Iterates through a page and coalesces free buffers. Called only after
   freeing allocated space on the page. Checks a buffer with its buddy and coalesces
   the two if both are free. */
void coalesce(pageheaderT* page)
{
  freelistL* buffer = get_required_buffer(1, page);
  allocheaderT* alloc;
  allocheaderT* prev = NULL;

  while (buffer != NULL)
  {
    alloc = buffer->first_block;
    while (alloc != NULL)
    {
      if (alloc->next != NULL && (get_buddy(alloc) == alloc->next))
      {
        if (prev == NULL)
          buffer->first_block = alloc->next->next;
        else
          prev->next = alloc->next->next;
        page->used += 1;
        kma_free(alloc, alloc->size * 2);
        return;
      }
      else
        alloc = alloc->next; 
    }
    buffer = buffer->bigger_size;
  }
}
Ejemplo n.º 2
0
int is_free(uint64_t pd) {
    uint64_t buddy = get_buddy(pd, descr_table[pd].level);
    while(descr_table[buddy].level > descr_table[pd].level) {
        pd = buddy;
    }
    return (descr_table[pd].is_free == PAGE_DESCRIPTOR_AVAILABLE);
//            && (descr_table[buddy].level != descr_table[pd].level
//                || descr_table[buddy].is_free == PAGE_DESCRIPTOR_AVAILABLE));
}
Ejemplo n.º 3
0
void buddy_deallocate(phys_t addr, unsigned int lvl) {
    uint64_t pd = addr_to_pd(addr);

    insert_to_level(lvl, descr_table + pd);
    descr_table[pd].is_free = PAGE_DESCRIPTOR_AVAILABLE;
    for(unsigned int i = lvl; i < MAX_SIZE - 1; ++i) {
        uint64_t buddy = get_buddy(pd, i);
        if(buddy >= dt_size ||
                !(descr_table[buddy].is_free == PAGE_DESCRIPTOR_AVAILABLE && descr_table[buddy].level == i)) {
            return;
        }
        merge(pd, buddy, i + 1);
    }
}
Ejemplo n.º 4
0
// the user programmer should provide the correct level
// correct === the current level is not empty, while the level below is
void push_down(unsigned int level) {
    assert_true((heads[level].next != NULL), "push_down first contract");
    assert_true((level > 0), "push_down second contract");
    assert_true((heads[level - 1].next == NULL), "push_down third contract");

    uint64_t pd_id =  heads[level].next->pd_id;
    uint64_t buddy_id = get_buddy(pd_id, level - 1);
    page_descr* pd = descr_table + pd_id;
    page_descr* buddy = descr_table + buddy_id;

    extract_from_level(level, pd);

    // it is significant that previous level is empty
    heads[level - 1].next = pd;
    set_page_descr(pd, pd->pd_id, PAGE_DESCRIPTOR_AVAILABLE, level - 1, heads + (level - 1), buddy);
    set_page_descr(buddy, buddy->pd_id, PAGE_DESCRIPTOR_AVAILABLE, level - 1, pd, NULL);
}
Ejemplo n.º 5
0
    bool MatchPool::pop(int size_type, std::vector<MatchEntity*> &camps) {
        if (camps.size() != size_t(_camp_size)) {
            return false;
        }

        // find entity for first camp
        MatchEntity *ent = camps[0];
        if (!top(*ent, size_type)) {
            return false;
        }

        // find others' camp members with size_type
        for (size_t i = 1;i < camps.size(); i++) {
            MatchEntity *opp = camps[i];
            if (!get_opponent(ent, opp, ent->size)) {
                return false;
            }
        }

        // find left members
        int size = ent->get_size();
        while (size < _team_size) {
            // find buddies
            if (!get_buddy(_team_size - size, camps[0])) {
                return false;
            }

            // find oppoents
            for (size_t i = 1;i < camps.size(); i++) {
                if (!get_opponent(camps[0], camps[i], _team_size - size)) {
                    return false;
                }
            }
            size += camps[0]->get_size();
        }
        return true;
    }
Ejemplo n.º 6
0
void shee(void *ptr) {
	/* Nothing to do */
	if (ptr == NULL) {
		return;
	}

//	LOG("BEFORE SHEE AVAIL MAP\n");
//	LOG("Mem_pool size = 2^%luB\n", mp.pool_size);
//	print_avail_map();

	struct block *b = B_HEAD(ptr);
	struct block *buddy = NULL;
	b->state = FREE;

//	LOG("Going to free:\n");
	//LOG("Shee block of size 2^%luB = %luB\n", b->k_size, pow2(b->k_size));
//	print_block_info(b);

	/* Combine free block if buddy-possible */
	unsigned long k_size = b->k_size;
	while (k_size < mp.pool_size) {
		/* Find my buddy */
		buddy = get_buddy(b, k_size);

		/* Is buddy available? */
		if (buddy->state == USED) {
			break;
		}
		/* Is buddy used somewhere inside? */
 		if (buddy->k_size != k_size) {
			break;
		}
	
		/* Combine buddies together */
		buddy->prev->next = buddy->next;
		buddy->next->prev = buddy->prev;
		k_size++;
		if (buddy < b) {
			b = buddy;
		}
	}

	/* Put block on proper 'avail' list */
	b->state = FREE;
	b->k_size = k_size;
	struct block *p;
	p = mp.avail[b->k_size].next;
	b->next = p;
	p->prev = b;
	b->prev = (struct block *) &mp.avail[b->k_size];
	mp.avail[b->k_size].next = b;


//	LOG("AFTER SHEE AVAIL MAP\n");
//	print_avail_map();
//	LOG("\n");

	//TODO: Bude provadet jine vlakno - vyresi se problem uklizeni poolu
	//  po neuspesnem shallocu, ktery byl proveden jako prvni
	/* Shrink down memory pool if possible */
	int enableDestroy = 1;
	while (enableDestroy && !list_empty(&mp.avail[mp.pool_size-1])) {
		b = mp.avail[mp.pool_size-1].next;
		buddy = get_buddy(b, mp.pool_size-1);
		/* Is 'b' free block on the top of the heap with half of the pool size? */
		if (b < buddy) {
			break;
		}

		/* Correct the 'avail' array of old pool */
		mp.avail[mp.pool_size].prev = (struct block *) &mp.avail[mp.pool_size];
		mp.avail[mp.pool_size].next = (struct block *) &mp.avail[mp.pool_size];

		LOG("--## SHRINKING ##--\n");
		/* Then we can shrink the heap/pool */
		if (sbrk(-pow2(b->k_size)) == (void *) -1) {
			perror("sbrk");
		}
		mp.pool_size--;
		LOG("Pool size is now %lu\n", mp.pool_size);

		/* Correct the 'avail' array */
		mp.avail[mp.pool_size].prev = (struct block *) &mp.avail[mp.pool_size];
		mp.avail[mp.pool_size].next = (struct block *) &mp.avail[mp.pool_size];

		/* If only the first block with 'avail' array is on heap, we can clean-up */
		if (mp.pool_size == mp.init_size) {
			LOG("--## POOL DESTROYED ##--\n");
			if (brk(mp.base_addr) == -1) {
				perror("brk");
			}
			mp.base_addr = NULL;

			break;
		}
	}
}
Ejemplo n.º 7
0
/* 
	add user:       ymsgr:addfriend?ID
	send message:   ymsgr:sendim?ID&m=MESSAGE
	add chatroom:   ymsgr:chat?ROOM
*/
static INT_PTR ServiceParseYmsgrLink(WPARAM wParam, LPARAM lParam)
{
	TCHAR *arg = (TCHAR*)lParam;
	if (arg == NULL) return 1; /* sanity check */

	/* skip leading prefix */
	arg = _tcschr(arg, ':');
	if (arg == NULL) return 1; /* parse failed */
	
	for (++arg; *arg == '/'; ++arg) {}

	if (g_instances.getCount() == 0) return 0;

	CYahooProto *proto = g_instances[0];
	for (int i = 0; i < g_instances.getCount(); ++i)
	{
		if (g_instances[i]->m_iStatus > ID_STATUS_OFFLINE)
		{
			proto = g_instances[i];
			break;
		}
	}
	if (!proto) return 1;

	/* add a contact to the list */
	if (!_tcsnicmp(arg, _T("addfriend?"), 10)) 
	{
		arg += 10;

		char *id = get_buddy(&arg);
		if (!id) return 1;
		
		if (proto->getbuddyH(id) == NULL) /* does not yet check if id is current user */
		{
			ADDCONTACTSTRUCT acs = {0};
			PROTOSEARCHRESULT psr = {0};
			
			acs.handleType = HANDLE_SEARCHRESULT;
			acs.szProto = proto->m_szModuleName;
			acs.psr = &psr;
			
			psr.cbSize = sizeof(PROTOSEARCHRESULT);
			psr.id = (TCHAR*)id;
			CallService(MS_ADDCONTACT_SHOW, 0, (LPARAM)&acs);
		}

		mir_free(id);
		return 0;
	}
	/* send a message to a contact */
	else if (!_tcsnicmp(arg, _T("sendim?"), 7)) 
	{
		arg += 7;

		char *id = get_buddy(&arg);
		if (!id) return 1;

		TCHAR *msg = NULL;

		while (arg) 
		{
			if (!_tcsnicmp(arg, _T("m="), 2))
			{
				msg = arg + 2;
				url_decode(msg);
				break;
			}
				
			arg = _tcschr(arg + 1, '&'); /* first token */
			if (arg) *arg = 0;
		}
			
		MCONTACT hContact = proto->add_buddy(id, id, 0, PALF_TEMPORARY); /* ensure contact is on list */
		if (hContact)
			CallService(MS_MSG_SENDMESSAGET, hContact, (LPARAM)msg);

		mir_free(id);
		return 0;
	}
	/* open a chatroom */
	else if (!_tcsnicmp(arg, _T("chat?"), 5)) 
	{
		arg += 5;

//		char *id = get_buddy(&arg);
//		if (!id) return 1;

		/* not yet implemented (rm contains name of chatroom)*/
		return 0;
	}
	return 1; /* parse failed */
}
Ejemplo n.º 8
0
errorcode helper_fsm_buddy_alloc(connlist_t *list, connlist_item_t *item) {

	/* declare variables */
	connlist_item_t *found_buddy = NULL;
	comm_msg_buddy_alloc_t msg;
	errorcode ret;

	/* error check arguments */
	CHECK_NOT_NULL(list,ERROR_NULL_ARG_1);
	CHECK_NOT_NULL(item,ERROR_NULL_ARG_2);

	/* do function */

	ret = SUCCESS;

	/* receive the waiting message */
	CHECK_FAILED(readMsg(item->info.socks.peer,
		COMM_MSG_WAITING_FOR_BUDDY_ALLOC,NULL,0),ERROR_NETWORK_READ);
	DEBUG(DBG_PROTOCOL,"PROTOCOL:received WAITING_FOR_BUDDY_ALLOC\n");


	/* get pointer to buddy's info*/
	if (FAILED(get_buddy(list,item,&found_buddy))){
		DEBUG(DBG_BUDDY,"BUDDY:couldn't find buddy\n");
		return ERROR_1;
	}

	DEBUG(DBG_BUDDY,"BUDDY:found buddy\n");
	/* check to make sure all buddy's info has been filled in,
	 * then fill in the message */

	if (FAILED(wait_for_buddy_port_alloc(&(found_buddy->info)))){
		ret = ERROR_1;
		goto forget_and_return;
	}

	msg.buddy_port_alloc = found_buddy->info.port_alloc.method;
	if ( (found_buddy->info.port_alloc.method == COMM_PORT_ALLOC_RAND) &&
	     (item->info.port_alloc.method == COMM_PORT_ALLOC_RAND)         )
		     msg.support = COMM_CONNECTION_UNSUPPORTED;
	else
		msg.support = COMM_CONNECTION_SUPPORTED;

	/* send out message*/
	if (FAILED(sendMsg(item->info.socks.peer,COMM_MSG_BUDDY_ALLOC,
		&msg,sizeof(comm_msg_buddy_alloc_t)))) {
		ret = ERROR_NETWORK_SEND;
		DEBUG(DBG_PROTOCOL,
			"fsm_buddy_alloc:PROTOCOL:sent BUDDY_ALLOC\n");
		goto forget_and_return;
	}

	if (msg.support == COMM_CONNECTION_UNSUPPORTED) {
		DEBUG(DBG_VERBOSE, "VERBOSE:connection unsupported!\n");
		ret = ERROR_2;
		goto forget_and_return;
	}


	/* enter next state */
	if (FAILED(helper_fsm_buddy_port(list,item,found_buddy))) {
		ret = ERROR_CALLED_FUNCTION;
		goto forget_and_return;
	}

forget_and_return:
	/* forget the buddy's info */
	DEBUG(DBG_LIST, "LIST:forgeting about buddy entry\n");
	CHECK_FAILED(connlist_forget(list,connlist_item_match,found_buddy),
		ERROR_3);
	return ret;
}