Ejemplo n.º 1
0
/*!	Duplicates an FD from another team to this/the kernel team.
	\param fromTeam The team which owns the FD.
	\param fd The FD to duplicate.
	\param kernel If \c true, the new FD will be created in the kernel team,
			the current userland team otherwise.
	\return The newly created FD or an error code, if something went wrong.
*/
int
dup_foreign_fd(team_id fromTeam, int fd, bool kernel)
{
	// get the I/O context for the team in question
	Team* team = Team::Get(fromTeam);
	if (team == NULL)
		return B_BAD_TEAM_ID;
	BReference<Team> teamReference(team, true);

	io_context* fromContext = team->io_context;

	// get the file descriptor
	file_descriptor* descriptor = get_fd(fromContext, fd);
	if (descriptor == NULL)
		return B_FILE_ERROR;
	CObjectDeleter<file_descriptor> descriptorPutter(descriptor, put_fd);

	// create a new FD in the target I/O context
	int result = new_fd(get_current_io_context(kernel), descriptor);
	if (result >= 0) {
		// the descriptor reference belongs to the slot, now
		descriptorPutter.Detach();
	}

	return result;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
status_t
user_timer_get_clock(clockid_t clockID, bigtime_t& _time)
{
	switch (clockID) {
		case CLOCK_MONOTONIC:
			_time = system_time();
			return B_OK;

		case CLOCK_REALTIME:
			_time = real_time_clock_usecs();
			return B_OK;

		case CLOCK_THREAD_CPUTIME_ID:
		{
			Thread* thread = thread_get_current_thread();
			InterruptsSpinLocker timeLocker(thread->time_lock);
			_time = thread->CPUTime(false);
			return B_OK;
		}

		case CLOCK_PROCESS_USER_CPUTIME_ID:
		{
			Team* team = thread_get_current_thread()->team;
			InterruptsSpinLocker timeLocker(team->time_lock);
			_time = team->UserCPUTime();
			return B_OK;
		}

		case CLOCK_PROCESS_CPUTIME_ID:
		default:
		{
			// get the ID of the target team (or the respective placeholder)
			team_id teamID;
			if (clockID == CLOCK_PROCESS_CPUTIME_ID) {
				teamID = B_CURRENT_TEAM;
			} else {
				if (clockID < 0)
					return B_BAD_VALUE;
				if (clockID == team_get_kernel_team_id())
					return B_NOT_ALLOWED;

				teamID = clockID;
			}

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

			// get the time
			InterruptsSpinLocker timeLocker(team->time_lock);
			_time = team->CPUTime(false);

			return B_OK;
		}
	}
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
0
status_t
_user_set_clock(clockid_t clockID, bigtime_t time)
{
	switch (clockID) {
		case CLOCK_MONOTONIC:
			return B_BAD_VALUE;

		case CLOCK_REALTIME:
			// only root may set the time
			if (geteuid() != 0)
				return B_NOT_ALLOWED;

			set_real_time_clock_usecs(time);
			return B_OK;

		case CLOCK_THREAD_CPUTIME_ID:
		{
			Thread* thread = thread_get_current_thread();
			InterruptsSpinLocker timeLocker(thread->time_lock);
			bigtime_t diff = time - thread->CPUTime(false);
			thread->cpu_clock_offset += diff;

			thread_clock_changed(thread, diff);
			return B_OK;
		}

		case CLOCK_PROCESS_USER_CPUTIME_ID:
			// not supported -- this clock is an Haiku-internal extension
			return B_BAD_VALUE;

		case CLOCK_PROCESS_CPUTIME_ID:
		default:
		{
			// get the ID of the target team (or the respective placeholder)
			team_id teamID;
			if (clockID == CLOCK_PROCESS_CPUTIME_ID) {
				teamID = B_CURRENT_TEAM;
			} else {
				if (clockID < 0)
					return B_BAD_VALUE;
				if (clockID == team_get_kernel_team_id())
					return B_NOT_ALLOWED;

				teamID = clockID;
			}

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

			// set the time offset
			InterruptsSpinLocker timeLocker(team->time_lock);
			bigtime_t diff = time - team->CPUTime(false);
			team->cpu_clock_offset += diff;

			team_clock_changed(team, diff);
			return B_OK;
		}
	}

	return B_OK;
}
Ejemplo n.º 8
0
/*!	Creates a semaphore with the given parameters.

	This function is only available from within the kernel, and
	should not be made public - if possible, we should remove it
	completely (and have only create_sem() exported).
*/
sem_id
create_sem_etc(int32 count, const char* name, team_id owner)
{
	struct sem_entry* sem = NULL;
	cpu_status state;
	sem_id id = B_NO_MORE_SEMS;
	char* tempName;
	size_t nameLength;

	if (sSemsActive == false || sUsedSems == sMaxSems)
		return B_NO_MORE_SEMS;

	if (name == NULL)
		name = "unnamed semaphore";

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

	// clone the name
	nameLength = strlen(name) + 1;
	nameLength = min_c(nameLength, B_OS_NAME_LENGTH);
	tempName = (char*)malloc(nameLength);
	if (tempName == NULL)
		return B_NO_MEMORY;

	strlcpy(tempName, name, nameLength);

	state = disable_interrupts();
	GRAB_SEM_LIST_LOCK();

	// get the first slot from the free list
	sem = sFreeSemsHead;
	if (sem) {
		// remove it from the free list
		sFreeSemsHead = sem->u.unused.next;
		if (!sFreeSemsHead)
			sFreeSemsTail = NULL;

		// init the slot
		GRAB_SEM_LOCK(*sem);
		sem->id = sem->u.unused.next_id;
		sem->u.used.count = count;
		sem->u.used.net_count = count;
		new(&sem->queue) ThreadQueue;
		sem->u.used.name = tempName;
		sem->u.used.owner = team->id;
		sem->u.used.select_infos = NULL;
		id = sem->id;

		list_add_item(&team->sem_list, &sem->u.used.team_link);

		RELEASE_SEM_LOCK(*sem);

		atomic_add(&sUsedSems, 1);

		KTRACE("create_sem_etc(count: %ld, name: %s, owner: %ld) -> %ld",
			count, name, owner, id);

		T_SCHEDULING_ANALYSIS(CreateSemaphore(id, name));
		NotifyWaitObjectListeners(&WaitObjectListener::SemaphoreCreated, id,
			name);
	}

	RELEASE_SEM_LIST_LOCK();
	restore_interrupts(state);

	if (sem == NULL)
		free(tempName);

	return id;
}