static void
dump_guarded_heap_area(guarded_heap_area& area)
{
	printf("guarded heap area: %p\n", &area);
	printf("next heap area: %p\n", area.next);
	printf("guarded heap: %p\n", area.heap);
	printf("area id: %" B_PRId32 "\n", area.area);
	printf("base: 0x%" B_PRIxADDR "\n", area.base);
	printf("size: %" B_PRIuSIZE "\n", area.size);
	printf("page count: %" B_PRIuSIZE "\n", area.page_count);
	printf("used pages: %" B_PRIuSIZE "\n", area.used_pages);
	printf("lock: %p\n", &area.lock);

	size_t freeCount = 0;
	void* item = list_get_next_item(&area.free_list, NULL);
	while (item != NULL) {
		freeCount++;

		if ((((guarded_heap_page*)item)->flags & GUARDED_HEAP_PAGE_FLAG_USED)
				!= 0) {
			printf("free list broken, page %p not actually free\n", item);
		}

		item = list_get_next_item(&area.free_list, item);
	}

	printf("free_list: %p (%" B_PRIuSIZE " free)\n", &area.free_list,
		freeCount);

	freeCount = 0;
	size_t runLength = 0;
	size_t longestRun = 0;
	for (size_t i = 0; i <= area.page_count; i++) {
		guarded_heap_page& page = area.pages[i];
		if (i == area.page_count
			|| (page.flags & GUARDED_HEAP_PAGE_FLAG_USED) != 0) {
			freeCount += runLength;
			if (runLength > longestRun)
				longestRun = runLength;
			runLength = 0;
			continue;
		}

		runLength = 1;
		for (size_t j = 1; j < area.page_count - i; j++) {
			if ((area.pages[i + j].flags & GUARDED_HEAP_PAGE_FLAG_USED) != 0)
				break;

			runLength++;
		}

		i += runLength - 1;
	}

	printf("longest free run: %" B_PRIuSIZE " (%" B_PRIuSIZE " free)\n",
		longestRun, freeCount);

	printf("pages: %p\n", area.pages);
}
static void*
guarded_heap_area_allocate(guarded_heap_area& area, size_t pagesNeeded,
	size_t size, size_t alignment)
{
	if (pagesNeeded > area.page_count - area.used_pages)
		return NULL;

	// We use the free list this way so that the page that has been free for
	// the longest time is allocated. This keeps immediate re-use (that may
	// hide bugs) to a minimum.
	guarded_heap_page* page
		= (guarded_heap_page*)list_get_next_item(&area.free_list, NULL);

	for (; page != NULL;
		page = (guarded_heap_page*)list_get_next_item(&area.free_list, page)) {

		if ((page->flags & GUARDED_HEAP_PAGE_FLAG_USED) != 0)
			continue;

		size_t pageIndex = page - area.pages;
		if (pageIndex > area.page_count - pagesNeeded)
			continue;

		// Candidate, check if we have enough pages going forward
		// (including the guard page).
		bool candidate = true;
		for (size_t j = 1; j < pagesNeeded; j++) {
			if ((area.pages[pageIndex + j].flags & GUARDED_HEAP_PAGE_FLAG_USED)
					!= 0) {
				candidate = false;
				break;
			}
		}

		if (!candidate)
			continue;

		size_t offset = size & (B_PAGE_SIZE - 1);
		void* result = (void*)((area.base + pageIndex * B_PAGE_SIZE
			+ (offset > 0 ? B_PAGE_SIZE - offset : 0)) & ~(alignment - 1));

		guarded_heap_page_allocate(area, pageIndex, pagesNeeded, size,
			alignment, result);

		area.used_pages += pagesNeeded;
		guarded_heap_pages_allocated(*area.heap, pagesNeeded);
		return result;
	}

	return NULL;
}
Example #3
0
static int
dump_images_list(int argc, char **argv)
{
	struct image *image = NULL;
	Team *team;

	if (argc > 1) {
		team_id id = strtol(argv[1], NULL, 0);
		team = team_get_team_struct_locked(id);
		if (team == NULL) {
			kprintf("No team with ID %ld found\n", id);
			return 1;
		}
	} else
		team = thread_get_current_thread()->team;

	kprintf("Registered images of team %ld\n", team->id);
	kprintf("    ID text       size    data       size    name\n");

	while ((image = (struct image*)list_get_next_item(&team->image_list, image))
			!= NULL) {
		image_info *info = &image->info;

		kprintf("%6ld %p %-7ld %p %-7ld %s\n", info->id, info->text, info->text_size,
			info->data, info->data_size, info->name);
	}

	return 0;
}
Example #4
0
status_t
_get_next_image_info(team_id teamID, int32 *cookie, image_info *info,
	size_t size)
{
	if (size > sizeof(image_info))
		return B_BAD_VALUE;

	// get the team
	Team* team = Team::Get(teamID);
	if (team == NULL)
		return B_BAD_TEAM_ID;
	BReference<Team> teamReference(team, true);

	// iterate through the team's images
	MutexLocker imageLocker(sImageMutex);

	struct image* image = NULL;
	int32 count = 0;

	while ((image = (struct image*)list_get_next_item(&team->image_list,
			image)) != NULL) {
		if (count == *cookie) {
			memcpy(info, &image->info.basic_info, size);
			(*cookie)++;
			return B_OK;
		}
		count++;
	}

	return B_ENTRY_NOT_FOUND;
}
Example #5
0
static int
dump_images_list(int argc, char **argv)
{
	struct image *image = NULL;
	Team *team;

	if (argc > 1) {
		team_id id = strtol(argv[1], NULL, 0);
		team = team_get_team_struct_locked(id);
		if (team == NULL) {
			kprintf("No team with ID %" B_PRId32 " found\n", id);
			return 1;
		}
	} else
		team = thread_get_current_thread()->team;

	kprintf("Registered images of team %" B_PRId32 "\n", team->id);
	kprintf("    ID %-*s   size    %-*s   size    name\n",
		B_PRINTF_POINTER_WIDTH, "text", B_PRINTF_POINTER_WIDTH, "data");

	while ((image = (struct image*)list_get_next_item(&team->image_list, image))
			!= NULL) {
		image_info *info = &image->info.basic_info;

		kprintf("%6" B_PRId32 " %p %-7" B_PRId32 " %p %-7" B_PRId32 " %s\n",
			info->id, info->text, info->text_size, info->data, info->data_size,
			info->name);
	}

	return 0;
}
static status_t
deliver_multicast(net_protocol_module_info* module, net_buffer* buffer,
	bool deliverToRaw)
{
	if (module->deliver_data == NULL)
		return B_OK;

	MutexLocker _(sMulticastGroupsLock);

	status_t status = B_OK;
	if (buffer->interface_address != NULL) {
		status = deliver_multicast(module, buffer, deliverToRaw,
			buffer->interface_address->interface);
	} else {
#if 0 //  FIXME: multicast
		net_domain_private* domain = (net_domain_private*)sDomain;
		RecursiveLocker locker(domain->lock);

		net_interface* interface = NULL;
		while (true) {
			interface = (net_interface*)list_get_next_item(
				&domain->interfaces, interface);
			if (interface == NULL)
				break;

			status = deliver_multicast(module, buffer, deliverToRaw, interface);
			if (status < B_OK)
				break;
		}
#endif
	}
	return status;
}
Example #7
0
snet_buffer*
snb_fetch(struct list* l, uint16 size)
{
	snet_buffer* item = NULL;
	snet_buffer* newitem = NULL;

	if (!list_is_empty(l))
	while ((item = (snet_buffer*)list_get_next_item(l, item)) != NULL) {
		if (item->allocatedSize >= size) {
			// This one is for us
			break;
		}
	}
	
	newitem = snb_attempt_reuse(item, size); 
	
	/* the resulting reused one is the same 
	 * as we fetched? => remove it from list
	 */
	if (item == newitem) {
		list_remove_item(l, item);
	}

	return newitem;
}
Example #8
0
status_t
image_debug_lookup_user_symbol_address(Team *team, addr_t address,
	addr_t *_baseAddress, const char **_symbolName, const char **_imageName,
	bool *_exactMatch)
{
	// TODO: Work together with ELF reader and runtime_loader. For regular user
	// images we have the symbol and string table addresses.

	struct image *image = NULL;

	while ((image = (struct image*)list_get_next_item(&team->image_list, image))
			!= NULL) {
		image_info *info = &image->info.basic_info;

		if ((address < (addr_t)info->text
				|| address >= (addr_t)info->text + info->text_size)
			&& (address < (addr_t)info->data
				|| address >= (addr_t)info->data + info->data_size))
			continue;

		// found image
		*_symbolName = NULL;
		*_imageName = info->name;
		*_baseAddress = (addr_t)info->text;
		*_exactMatch = false;

		return B_OK;
	}

	return B_ENTRY_NOT_FOUND;
}
Example #9
0
uint16
snb_packets(struct list* l)
{
	uint16 count = 0;
	snet_buffer* item = NULL;
	
	while ((item = (snet_buffer*)list_get_next_item(l, item)) != NULL)
		count++;
	
	return count;
}
Example #10
0
/*!	Called by the get_next_sem_info() macro. */
status_t
_get_next_sem_info(team_id teamID, int32 *_cookie, struct sem_info *info,
	size_t size)
{
	if (!sSemsActive)
		return B_NO_MORE_SEMS;
	if (_cookie == NULL || info == NULL || size != sizeof(sem_info))
		return B_BAD_VALUE;
	if (teamID < 0)
		return B_BAD_TEAM_ID;

	Team* team = Team::Get(teamID);
	if (team == NULL)
		return B_BAD_TEAM_ID;
	BReference<Team> teamReference(team, true);

	InterruptsSpinLocker semListLocker(sSemsSpinlock);

	// TODO: find a way to iterate the list that is more reliable
	sem_entry* sem = (sem_entry*)list_get_first_item(&team->sem_list);
	int32 newIndex = *_cookie;
	int32 index = 0;
	bool found = false;

	while (!found) {
		// find the next entry to be returned
		while (sem != NULL && index < newIndex) {
			sem = (sem_entry*)list_get_next_item(&team->sem_list, sem);
			index++;
		}

		if (sem == NULL)
			return B_BAD_VALUE;

		GRAB_SEM_LOCK(*sem);

		if (sem->id != -1 && sem->u.used.owner == team->id) {
			// found one!
			fill_sem_info(sem, info, size);
			newIndex = index + 1;
			found = true;
		} else
			newIndex++;

		RELEASE_SEM_LOCK(*sem);
	}

	if (!found)
		return B_BAD_VALUE;

	*_cookie = newIndex;
	return B_OK;
}
Example #11
0
/*!	Counts the registered images from the specified team.
	Interrupts must be enabled.
*/
int32
count_images(Team *team)
{
	struct image *image = NULL;
	int32 count = 0;

	MutexLocker locker(sImageMutex);

	while ((image = (struct image*)list_get_next_item(&team->image_list, image))
			!= NULL) {
		count++;
	}

	return count;
}
Example #12
0
void
snb_park(struct list* l, snet_buffer* snb)
{
	snet_buffer* item = NULL;

	// insert it by order
	while ((item = (snet_buffer*)list_get_next_item(l, item)) != NULL) {
		// This one has allocated more than us place us back
		if (item->allocatedSize > snb->allocatedSize) {
			list_insert_item_before(l, item, snb);
			return;
		}
	}
	// no buffer bigger than us(or empty).. then at the end
	list_add_item(l, snb);
}
Example #13
0
ssize_t
socket_count_connected(net_socket *_parent)
{
	net_socket_private *parent = (net_socket_private *)_parent;

	MutexLocker _(parent->lock);

	ssize_t count = 0;
	void *item = NULL;
	while ((item = list_get_next_item(&parent->connected_children,
			item)) != NULL) {
		count++;
	}

	return count;
}
Example #14
0
static int
dump_domains(int argc, char** argv)
{
	DomainList::Iterator iterator = sDomains.GetIterator();
	while (net_domain_private* domain = iterator.Next()) {
		kprintf("domain: %p, %s, %d\n", domain, domain->name, domain->family);
		kprintf("  module:         %p\n", domain->module);
		kprintf("  address_module: %p\n", domain->address_module);
		
		if (!list_is_empty(&domain->interfaces))
			kprintf("  interfaces:\n");

		net_interface* interface = NULL;
		while (true) {
			interface = (net_interface*)list_get_next_item(&domain->interfaces,
				interface);
			if (interface == NULL)
				break;

			kprintf("    %p\n", interface);
		}

		if (!domain->routes.IsEmpty())
			kprintf("  routes:\n");
	
		RouteList::Iterator routeIterator = domain->routes.GetIterator();
		while (net_route* route = routeIterator.Next()) {
			kprintf("    %p\n", route);
		}

		if (!domain->route_infos.IsEmpty())
			kprintf("  route infos:\n");
	
		RouteInfoList::Iterator infoIterator = domain->route_infos.GetIterator();
		while (net_route_info* info = infoIterator.Next()) {
			kprintf("    %p\n", info);
		}
	}

	return 0;
}
Example #15
0
uint32
count_domain_interfaces()
{
	MutexLocker locker(sDomainLock);

	uint32 count = 0;

	DomainList::Iterator iterator = sDomains.GetIterator();
	while (net_domain_private* domain = iterator.Next()) {
		net_interface* interface = NULL;
		while (true) {
			interface = (net_interface*)list_get_next_item(&domain->interfaces,
				interface);
			if (interface == NULL)
				break;

			count++;
		}
	}

	return count;
}
Example #16
0
status_t
copy_images(team_id fromTeamId, Team *toTeam)
{
	// get the team
	Team* fromTeam = Team::Get(fromTeamId);
	if (fromTeam == NULL)
		return B_BAD_TEAM_ID;
	BReference<Team> teamReference(fromTeam, true);

	MutexLocker locker(sImageMutex);

	struct image *image = NULL;
	while ((image = (struct image*)list_get_next_item(&fromTeam->image_list,
			image)) != NULL) {
		image_id id = register_image(toTeam, &image->info, sizeof(image->info),
			true);
		if (id < 0)
			return id;
	}

	return B_OK;
}
Example #17
0
/*!	Dumps a list of all interfaces into the supplied userland buffer.
	If the interfaces don't fit into the buffer, an error (\c ENOBUFS) is
	returned.
*/
status_t
list_domain_interfaces(void* _buffer, size_t* bufferSize)
{
	MutexLocker locker(sDomainLock);

	UserBuffer buffer(_buffer, *bufferSize);

	DomainList::Iterator iterator = sDomains.GetIterator();
	while (net_domain_private* domain = iterator.Next()) {
		RecursiveLocker locker(domain->lock);

		net_interface* interface = NULL;
		while (true) {
			interface = (net_interface*)list_get_next_item(&domain->interfaces,
				interface);
			if (interface == NULL)
				break;

			ifreq request;
			strlcpy(request.ifr_name, interface->name, IF_NAMESIZE);
			if (interface->address != NULL) {
				memcpy(&request.ifr_addr, interface->address,
					interface->address->sa_len);
			} else {
				// empty address
				request.ifr_addr.sa_len = 2;
				request.ifr_addr.sa_family = AF_UNSPEC;
			}

			if (buffer.Copy(&request, IF_NAMESIZE
					+ request.ifr_addr.sa_len) == NULL)
				return buffer.Status();
		}
	}

	*bufferSize = buffer.ConsumedAmount();
	return B_OK;
}
Example #18
0
struct image*
image_iterate_through_team_images(team_id teamID,
	image_iterator_callback callback, void* cookie)
{
	// get the team
	Team* team = Team::Get(teamID);
	if (team == NULL)
		return NULL;
	BReference<Team> teamReference(team, true);

	// iterate through the team's images
	MutexLocker imageLocker(sImageMutex);

	struct image* image = NULL;

	while ((image = (struct image*)list_get_next_item(&team->image_list,
			image)) != NULL) {
		if (callback(image, cookie))
			break;
	}

	return image;
}
Example #19
0
static int
dump_driver(int argc, char** argv)
{
	int i;
	snet_buffer* item = NULL;

	for (i = 0; i < MAX_BT_GENERIC_USB_DEVICES; i++) {

		if (bt_usb_devices[i] != NULL) {
			kprintf("%s : \n", bt_usb_devices[i]->name);
			kprintf("\taclroom = %d\teventroom = %d\tcommand & events =%d\n",
				snb_packets(&bt_usb_devices[i]->eventRoom),
				snb_packets(&bt_usb_devices[i]->aclRoom),
				snb_packets(&bt_usb_devices[i]->snetBufferRecycleTrash));

			while ((item = (snet_buffer*)list_get_next_item(
				&bt_usb_devices[i]->snetBufferRecycleTrash, item)) != NULL)
				snb_dump(item);
		}
	}

	return 0;
}
Example #20
0
static status_t
callout_thread(void* /*data*/)
{
    status_t status = B_OK;

    do {
        bigtime_t timeout = B_INFINITE_TIMEOUT;

        if (status == B_TIMED_OUT || status == B_OK) {
            // scan timers for new timeout and/or execute a timer
            mutex_lock(&sLock);

            struct callout* c = NULL;
            while (true) {
                c = (callout*)list_get_next_item(&sTimers, c);
                if (c == NULL)
                    break;

                if (c->due < system_time()) {
                    struct mtx *mutex = c->c_mtx;

                    // execute timer
                    list_remove_item(&sTimers, c);
                    c->due = -1;
                    sCurrentCallout = c;

                    mutex_unlock(&sLock);

                    if (mutex != NULL)
                        mtx_lock(mutex);

                    c->c_func(c->c_arg);

                    if (mutex != NULL)
                        mtx_unlock(mutex);

                    mutex_lock(&sLock);

                    sCurrentCallout = NULL;
                    c = NULL;
                    // restart scanning as we unlocked the list
                } else {
                    // calculate new timeout
                    if (c->due < timeout)
                        timeout = c->due;
                }
            }

            sTimeout = timeout;
            mutex_unlock(&sLock);
        }

        status = acquire_sem_etc(sWaitSem, 1, B_ABSOLUTE_TIMEOUT, timeout);
        // the wait sem normally can't be acquired, so we
        // have to look at the status value the call returns:
        //
        // B_OK - a new timer has been added or canceled
        // B_TIMED_OUT - look for timers to be executed
        // B_BAD_SEM_ID - we are asked to quit
    } while (status != B_BAD_SEM_ID);

    return B_OK;
}