Пример #1
0
	size_t size() const
	{
		SHM_HDR_TYPE* hdr = lock_memory();
		size_type r = hdr->count;
		unlock_memory();
		return size_t(r);
	}
Пример #2
0
	bool push_front(const void * data, size_t size)
	{
		SHM_HDR_TYPE*  hdr = lock_memory();
		size_type new_front = static_cast<size_type>(hdr->front - sizeof(SHM_DATA_HDR_TYPE) - size);
		if( m_length < new_front ) {
			new_front = static_cast<size_type>(m_length - sizeof(SHM_DATA_HDR_TYPE) - size);
		}
		if( (hdr->back + m_length - hdr->front) % m_length <
		    (hdr->back + m_length - new_front)  % m_length )
		{
			SHM_DATA_TYPE* ptr = reinterpret_cast<SHM_DATA_TYPE*>(
			                     reinterpret_cast<unsigned char*>(hdr + 1) + new_front);
			hdr->count++;
			hdr->front  = new_front;
			ptr->length = static_cast<size_type>(size);
			::memcpy(ptr->data, &data, size);
			if( 1 == hdr->count ) {
				hdr->back_minus1 = new_front;
			}
			unlock_memory();
			return true;
		} else {
			unlock_memory();
			return false;
		}
	}
Пример #3
0
bool
create_temp_sg(scsi_ccb *ccb)
{
	physical_entry *temp_sg;
	status_t res;

	SHOW_FLOW(3, "ccb=%p, data=%p, data_length=%" B_PRIu32, ccb, ccb->data,
		ccb->data_length);

	ccb->sg_list = temp_sg = (physical_entry*)locked_pool->alloc(temp_sg_pool);
	if (temp_sg == NULL) {
		SHOW_ERROR0(2, "cannot allocate memory for IO request!");
		return false;
	}

	res = lock_memory(ccb->data, ccb->data_length, B_DMA_IO
		| ((ccb->flags & SCSI_DIR_MASK) == SCSI_DIR_IN ? B_READ_DEVICE : 0));

	if (res != B_OK) {
		SHOW_ERROR(2, "cannot lock memory for IO request (%s)", strerror(res));
		goto err;
	}

	if (fill_temp_sg(ccb))
		// this is the success path
		return true;

	unlock_memory(ccb->data, ccb->data_length, B_DMA_IO
		| ((ccb->flags & SCSI_DIR_MASK) == SCSI_DIR_IN ? B_READ_DEVICE : 0));

err:
	locked_pool->free(temp_sg_pool, temp_sg);
	return false;
}
Пример #4
0
	bool empty() const
	{
		SHM_HDR_TYPE* hdr = lock_memory();
		bool r = !hdr->count;
		unlock_memory();
		return r;
	}
Пример #5
0
static unsigned char* allocRaw(uint32 objectSize, unsigned char* store, uint32 *top, uint32 size, char clear) {
#ifdef USEMALLOCFREE
    return calloc(objectSize, 1);
#else
    unsigned char* obj = 0;
    int count;

    while ((*top) & 0x3) {
        (*top)++;
    };

    lock_memory();
    count = *top;
    *top += objectSize;

    if (*top < size) {
        obj = HEAP_REF(store, unsigned char*) + count;
        if (clear) {
            unsigned char* src;
            src = (unsigned char*) obj;
            count = *top - count;
            while (count > 0) {
                *src++ = 0;
                count--;
            }
        }
    }
Пример #6
0
void do_pagefault(struct pf_msg *pmsg)
{
   int frame;
   int page;

   verify_vm_access(pmsg->page_idx, pmsg->word_idx);

   frame = find_pgt_index();
   page = find_vm_index(frame);

   lock_memory();
   lock_vm();
   lock_pagetable();

   //printf("Swapping out frame %d\n", frame);

   swap_out(page, frame);
   usleep(F);

   //printf("Swapping in page %d\n", pmsg->page_idx);
   swap_in(pmsg->page_idx, frame);
   usleep(F);

   page_table[page] = -1;
   page_table[pmsg->page_idx] = frame;

   unlock_memory();
   unlock_vm();
   unlock_pagetable();
}
Пример #7
0
	void pop_back()
	{
		SHM_HDR_TYPE* hdr = lock_memory();
		if( hdr->count )
		{
			size_type new_back_minus1 = hdr->front;
			for(size_type seek = hdr->front;
				seek != hdr->back_minus1; )
			{
				SHM_DATA_TYPE* ptr = reinterpret_cast<SHM_DATA_TYPE*>(
				                     reinterpret_cast<unsigned char*>(hdr + 1) + seek);
				new_back_minus1 = seek;
				seek           += sizeof(SHM_DATA_HDR_TYPE) + ptr->length;
				if( m_length <= seek ) {
					seek = 0;
				}
			}
			hdr->back       = hdr->back_minus1;
			hdr->back_minus1= new_back_minus1;
			hdr->count--;
			unlock_memory();
		} else {
			unlock_memory();
			assert(false);
		}
	}
Пример #8
0
	bool back(void * buff, size_t size)
	{
		SHM_HDR_TYPE*  hdr = lock_memory();
		SHM_DATA_TYPE* ptr = reinterpret_cast<SHM_DATA_TYPE*>(
		                     reinterpret_cast<unsigned char*>(hdr + 1) + hdr->back_minus1);
		if( hdr->count && size == ptr->length ) {
			::memcpy(buff, ptr->data, size);
			unlock_memory();
			return true;
		} else {
			unlock_memory();
			assert(false);
			return false;
		}
	}
Пример #9
0
	void pop_front()
	{
		SHM_HDR_TYPE* hdr = lock_memory();
		SHM_DATA_TYPE* ptr = reinterpret_cast<SHM_DATA_TYPE*>(
		                     reinterpret_cast<unsigned char*>(hdr + 1) + hdr->front);
		if( hdr->count ) {
			hdr->front += sizeof(SHM_DATA_HDR_TYPE) + ptr->length;
			if( m_length <= hdr->front ) {
				hdr->front = 0;
			}
			hdr->count--;
			unlock_memory();
		} else {
			unlock_memory();
			assert(false);
		}
	}
Пример #10
0
int64
_user_atomic_get64(vint64 *value)
{
	cpu_status status;
	int64 oldValue;
	if (!IS_USER_ADDRESS(value)
		|| lock_memory((void *)value, 8, B_READ_DEVICE) != B_OK)
		goto access_violation;

	status = disable_interrupts();
	acquire_spinlock(&atomic_lock);
	oldValue = *value;
	release_spinlock(&atomic_lock);
	restore_interrupts(status);
	unlock_memory((void *)value, 8, B_READ_DEVICE);
	return oldValue;

access_violation:
	// XXX kill application
	return -1;
}
Пример #11
0
	bool push_back(const void * data, size_t size)
	{
		SHM_HDR_TYPE*  hdr = lock_memory();
		size_type new_back = static_cast<size_type>(hdr->back + sizeof(SHM_DATA_HDR_TYPE) + size);
		if( m_length <= new_back ) {
			new_back = 0;
		}
		if( (hdr->back + m_length - hdr->front) % m_length <
		    (new_back  + m_length - hdr->front) % m_length )
		{
			SHM_DATA_TYPE* ptr = reinterpret_cast<SHM_DATA_TYPE*>(
			                     reinterpret_cast<unsigned char*>(hdr + 1) + hdr->back);
			hdr->count++;
			hdr->back_minus1= hdr->back;
			hdr->back   = new_back;
			ptr->length = static_cast<size_type>(size);
			::memcpy(ptr->data, data, size);
			unlock_memory();
			return true;
		} else {
			unlock_memory();
			return false;
		}
	}
Пример #12
0
// prepare DMA engine to copy data from graphics mem to other mem
static status_t Radeon_PrepareDMA( 
	device_info *di, uint32 src, char *target, size_t size, bool lock_mem, bool contiguous )
{
	physical_entry map[16];
	status_t res;
	DMA_descriptor *cur_desc;
	int num_desc;

	if( lock_mem && !contiguous ) {
		res = lock_memory( target, size, B_DMA_IO | B_READ_DEVICE );
	
		if( res != B_OK ) {
			SHOW_ERROR( 2, "Cannot lock memory (%s)", strerror( res ));
			return res;
		}
	}

	// adjust virtual address for graphics card
	src += di->si->memory[mt_local].virtual_addr_start;
	
	cur_desc = (DMA_descriptor *)(di->si->local_mem + di->dma_desc_offset);
	num_desc = 0;
	
	// memory may be fragmented, so we create S/G list
	while( size > 0 ) {
		int i;
	
		if( contiguous ) {
			// if memory is contiguous, ask for start address only to reduce work
			get_memory_map( target, 1, map, 16 );
			// replace received size with total size
			map[0].size = size;
		} else {
			get_memory_map( target, size, map, 16 );
		}
		
		for( i = 0; i < 16; ++i ) {
			uint32 address = (uint32)map[i].address;
			size_t contig_size = map[i].size;
			
			if( contig_size == 0 )
				break;
				
			target += contig_size;
				
			while( contig_size > 0 ) {
				size_t cur_size;
				
				cur_size = min( contig_size, RADEON_DMA_DESC_MAX_SIZE );
				
				if( ++num_desc > (int)di->dma_desc_max_num ) {
					SHOW_ERROR( 2, "Overflow of DMA descriptors, %ld bytes left", size );
					res = B_BAD_VALUE;
					goto err;
				}
				
				cur_desc->src_address = src;
				cur_desc->dest_address = address;
				cur_desc->command = cur_size;
				cur_desc->res = 0;
			
				++cur_desc;
				address += cur_size;
				contig_size -= cur_size;
				src += cur_size;
				size -= cur_size;
			}
		}
	}
	
	// mark last descriptor as being last one	
	(cur_desc - 1)->command |= RADEON_DMA_COMMAND_EOL;
	
	return B_OK;
	
err:
	if( lock_mem && !contiguous )
		unlock_memory( target, size, B_DMA_IO| B_READ_DEVICE );
		
	return res;
}
Пример #13
0
void run_script(struct config *config, struct script *script)
{
	char *error = NULL;
	struct state *state = NULL;
	struct netdev *netdev = NULL;
	struct event *event = NULL;

	DEBUGP("run_script: running script\n");

	set_scheduling_priority();
	lock_memory();

	/* This interpreter loop runs for local mode or wire client mode. */
	assert(!config->is_wire_server);

	/* How we use the network is of course a little different in
	 * each of the two cases....
	 */
	if (config->is_wire_client)
		netdev = wire_client_netdev_new(config);
	else
		netdev = local_netdev_new(config);

	state = state_new(config, script, netdev);

	if (config->is_wire_client)
	{
		state->wire_client = wire_client_new();
		wire_client_init(state->wire_client, config, script, state);
	}

	if (script->init_command != NULL)
	{
		if (safe_system(script->init_command->command_line,
		                &error))
		{
			die("%s: error executing init command: %s\n",
			    config->script_path, error);
		}
	}

	signal(SIGPIPE, SIG_IGN);	/* ignore EPIPE */

	state->live_start_time_usecs = schedule_start_time_usecs();
	DEBUGP("live_start_time_usecs is %lld\n",
	       state->live_start_time_usecs);

	if (state->wire_client != NULL)
		wire_client_send_client_starting(state->wire_client);

	while (1)
	{
		if (get_next_event(state, &error))
			die("%s", error);
		event = state->event;
		if (event == NULL)
			break;

		if (state->wire_client != NULL)
			wire_client_next_event(state->wire_client, event);

		/* In wire mode, we adjust relative times after
		 * getting notification that previous packet events
		 * have completed, if any.
		 */
		adjust_relative_event_times(state, event);

		switch (event->type)
		{
		case PACKET_EVENT:
			/* For wire clients, the server handles packets. */
			if (!config->is_wire_client)
			{
				run_local_packet_event(state, event,
				                       event->event.packet);
			}
			break;
		case SYSCALL_EVENT:
			run_system_call_event(state, event,
			                      event->event.syscall);
			break;
		case COMMAND_EVENT:
			run_command_event(state, event,
			                  event->event.command);
			break;
		case CODE_EVENT:
			run_code_event(state, event,
			               event->event.code->text);
			break;
		case INVALID_EVENT:
		case NUM_EVENT_TYPES:
			assert(!"bogus type");
			break;
			/* We omit default case so compiler catches missing values. */
		}
	}

	/* Wait for any outstanding packet events we requested on the server. */
	if (state->wire_client != NULL)
		wire_client_next_event(state->wire_client, NULL);

	if (code_execute(state->code, &error))
	{
		die("%s: error executing code: %s\n",
		    state->config->script_path, error);
		free(error);
	}

	state_free(state);

	DEBUGP("run_script: done running\n");
}
Пример #14
0
int main(int argc, char** argv)
{
	int num_cpus = 1; /* only do preemptions by default */
	int wss = 64;     /* working set size, in kb */
	int sleep_min = 0;
	int sleep_max = 1000;
	int exit_after = 0; /* seconds */
	int write_cycle = 0; /* every nth cycle is a write; 0 means read-only  */
	FILE* out = stdout;
	char fname[255];
	char *prefix = "pmo";
	struct utsname utsname;
	int auto_name_file = 0;
	int sample_count = 0;
	int opt;
	int best_effort = 0;
	int repetitions = 1;
	int i;

	srand (time(NULL));

	while ((opt = getopt(argc, argv, OPTSTR)) != -1) {
		switch (opt) {
		case 'm':
			num_cpus = atoi(optarg);
			break;
		case 'c':
			sample_count = atoi(optarg);
			break;
		case 's':
			wss = atoi(optarg);
			break;
		case 'w':
			write_cycle = atoi(optarg);
			break;
		case 'l':
			exit_after = atoi(optarg);
			break;
		case 'o':
			out = fopen(optarg, "w");
			if (out == NULL)
				usage("could not open file");
			break;
		case 'n':
			auto_name_file = 1;
			break;
		case 'P':
			prefix = optarg;
			break;
		case 'x':
			sleep_min = atoi(optarg);
			break;
		case 'y':
			sleep_max = atoi(optarg);
			break;
		case 'b':
			best_effort = 1;
			break;
		case 'R':
			repetitions = atoi(optarg);
			if (repetitions <= 0)
				usage("invalid number of repetitions");
			break;
		case 'h':
			usage(NULL);
			break;
		case ':':
			usage("Argument missing.");
			break;
		case '?':
		default:
			usage("Bad argument.");
			break;
		}
	}

	if (num_cpus <= 0)
		usage("Number of CPUs must be positive.");

	if (wss <= 0)
		usage("The working set size must be positive.");

	if (sleep_min < 0 || sleep_min > sleep_max)
		usage("Invalid minimum sleep time");

	if (write_cycle < 0)
		usage("Write cycle may not be negative.");

	if (sample_count < 0)
		usage("Sample count may not be negative.");

	if (check_migrations(num_cpus) != 0)
		usage("Invalid CPU range.");

	if (!best_effort && become_posix_realtime_task() != 0)
		die("Could not become real-time task.");

	if (!best_effort && lock_memory() != 0)
		die("Could not lock memory.");

	if (auto_name_file) {
		uname(&utsname);
		snprintf(fname, 255,
			 "%s_host=%s_wss=%d_wcycle=%d_smin=%d_smax=%d.csv",
			 prefix,
			 utsname.nodename, wss, write_cycle, sleep_min, sleep_max);
		out = fopen(fname, "w");
		if (out == NULL) {
			fprintf(stderr, "Can't open %s.", fname);
			die("I/O");
		}
	}

	if (exit_after > 0) {
		signal(SIGALRM, on_sigalarm);
		alarm(exit_after);
	}

	if (best_effort) {
		fprintf(out, "\n[!!!] WARNING: running in best-effort mode "
		             "=> all measurements are unreliable!\n\n");
	}


	for (i = 0; i < repetitions; i++)
		do_random_experiment(out,
			             num_cpus, wss, sleep_min,
			             sleep_max, write_cycle,
			             sample_count,
			             best_effort);
	fclose(out);
	return 0;
}
Пример #15
0
int main(int argc, char **argv) {
	int result = 0;
	int i;

  userui_ops[0] = &userui_text_ops;
	userui_ops[1] = FBSPLASH_OPS;
	userui_ops[2] = USPLASH_OPS;
	active_ops = &userui_text_ops;

	handle_params(argc, argv);
	setup_signal_handlers();
	open_console();
	open_misc();
	if (!test_run) {
		open_netlink();
		get_nofreeze();
		get_info();
	}

	lock_memory();

	prepare_console();

	/* Initialise all that we can, use the first */
//  active_ops = NULL;
	for (i = 0; i < NUM_UIS; i++) {
		if (userui_ops[i] && userui_ops[i]->load) {
			result = userui_ops[i]->load();
			if (result) {
				if (test_run)
					fprintf(stderr, "Failed to initialise %s module.\n", userui_ops[i]->name);
				else
					printk("Failed to initialise %s module.\n", userui_ops[i]->name);
			} else
				if (!active_ops)
					active_ops = userui_ops[i];
		}
	}

	if (active_ops->prepare)
		active_ops->prepare();

	register_keypress_handler();

	need_cleanup = 1;
	running = 1;

	result = nice(1);

	if (active_ops->memory_required)
		reserve_memory(active_ops->memory_required());
	else
		reserve_memory(4*1024*1024); /* say 4MB */

	enforce_lifesavers();

	if (test_run) {
		safe_to_exit = 0;

		do_test_run();
		return 0;
	}

	if (send_ready())
		message_loop();

	/* The only point we ever reach here is if message_loop crashed out.
	 * If this is the case, we should spin for a few hours before exiting to
	 * ensure that we don't corrupt stuff on disk (if we're past the atomic
	 * copy).
	 */
	sleep(60*60*1); /* 1 hours */
	_exit(1);
}
Пример #16
0
int
main (int argc, char *argv[])
{
    int   fd = -1;
    char *log_identity = argv[0];
    int   log_priority = LOG_INFO;
    int   log_options = LOG_OPT_PRIORITY;

#ifndef NDEBUG
    log_priority = LOG_DEBUG;
    log_options |= LOG_OPT_TIMESTAMP;
#endif /* NDEBUG */
    log_open_file (stderr, log_identity, log_priority, log_options);

    disable_core_dumps ();
    conf = create_conf ();
    parse_cmdline (conf, argc, argv);
    auth_recv_init (conf->auth_server_dir, conf->auth_client_dir,
        conf->got_force);

    if (!conf->got_foreground) {
        fd = daemonize_init (argv[0]);
        if (conf->got_syslog) {
            log_open_file (NULL, NULL, 0, 0);
            log_open_syslog (log_identity, LOG_DAEMON);
        }
        else {
            open_logfile (conf->logfile_name, log_priority, conf->got_force);
        }
    }
    handle_signals ();
    lookup_ip_addr (conf);
    write_pidfile (conf->pidfile_name, conf->got_force);
    if (conf->got_mlockall) {
        lock_memory ();
    }
    crypto_init ();
    if (random_init (conf->seed_name) < 0) {
        if (conf->seed_name) {
            free (conf->seed_name);
            conf->seed_name = NULL;
        }
    }
    create_subkeys (conf);
    conf->gids = gids_create (conf->gids_update_secs, conf->got_group_stat);
    replay_init ();
    timer_init ();
    sock_create (conf);

    if (!conf->got_foreground) {
        daemonize_fini (fd);
    }
    log_msg (LOG_NOTICE, "Starting %s daemon (pid %d)",
        META_ALIAS, (int) getpid ());

    job_accept (conf);

    sock_destroy (conf);
    timer_fini ();
    replay_fini ();
    gids_destroy (conf->gids);
    random_fini (conf->seed_name);
    crypto_fini ();
    destroy_conf (conf);

    log_msg (LOG_NOTICE, "Stopping %s daemon (pid %d)",
        META_ALIAS, (int) getpid ());

    exit (EMUNGE_SUCCESS);
}
Пример #17
0
/* Handle a wire connection from a client. */
static void *wire_server_thread(void *arg)
{
	struct wire_server *wire_server = (struct wire_server *)arg;
	struct netdev *netdev = NULL;
	char *error = NULL;

	DEBUGP("wire_server_thread\n");

	set_default_config(&wire_server->config);

	if (wire_server_receive_args(wire_server))
		goto error_done;

	if (wire_server_receive_script_path(wire_server))
		goto error_done;

	if (wire_server_receive_script(wire_server))
		goto error_done;

	if (wire_server_receive_hw_address(wire_server))
		goto error_done;

	if (parse_script_and_set_config(wire_server->argc,
						wire_server->argv,
						&wire_server->config,
						&wire_server->script,
						wire_server->script_path,
						wire_server->script_buffer))
		goto error_done;

	set_scheduling_priority();
	lock_memory();

	netdev =
	  wire_server_netdev_new(&wire_server->config,
				 wire_server->wire_server_device,
				 &wire_server->client_ether_addr,
				 &wire_server->server_ether_addr);

	wire_server->state = state_new(&wire_server->config,
					       &wire_server->script,
					       netdev);

	if (wire_server_send_server_ready(wire_server))
		goto error_done;

	if (wire_server_receive_client_starting(wire_server))
		goto error_done;

	if (wire_server_run_script(wire_server, &error))
		goto error_done;

	DEBUGP("wire_server_thread: finished test successfully\n");

error_done:
	if (error != NULL)
		fprintf(stderr, "%s\n", error);

	if (wire_server->state != NULL)
		state_free(wire_server->state, 0);

	DEBUGP("wire_server_thread: connection is done\n");
	wire_server_free(wire_server);
	return NULL;
}
Пример #18
0
status_t
SystemProfiler::Init()
{
	// clone the user area
	void* areaBase;
	fKernelArea = clone_area("profiling samples", &areaBase,
		B_ANY_KERNEL_ADDRESS, B_READ_AREA | B_WRITE_AREA,
		fUserArea);
	if (fKernelArea < 0)
		return fKernelArea;

	// we need the memory locked
	status_t error = lock_memory(areaBase, fAreaSize, B_READ_DEVICE);
	if (error != B_OK) {
		delete_area(fKernelArea);
		fKernelArea = -1;
		return error;
	}

	// the buffer is ready for use
	fHeader = (system_profiler_buffer_header*)areaBase;
	fBufferBase = (uint8*)(fHeader + 1);
	fBufferCapacity = fAreaSize - (fBufferBase - (uint8*)areaBase);
	fHeader->start = 0;
	fHeader->size = 0;

	// allocate the wait object buffer and init the hash table
	if (fWaitObjectCount > 0) {
		fWaitObjectBuffer = new(std::nothrow) WaitObject[fWaitObjectCount];
		if (fWaitObjectBuffer == NULL)
			return B_NO_MEMORY;

		for (int32 i = 0; i < fWaitObjectCount; i++)
			fFreeWaitObjects.Add(fWaitObjectBuffer + i);

		error = fWaitObjectTable.Init(fWaitObjectCount * 3 / 2);
		if (error != B_OK)
			return error;
	}

	// start listening for notifications

	// teams
	NotificationManager& notificationManager
		= NotificationManager::Manager();
	if ((fFlags & B_SYSTEM_PROFILER_TEAM_EVENTS) != 0) {
		error = notificationManager.AddListener("teams",
			TEAM_ADDED | TEAM_REMOVED | TEAM_EXEC, *this);
		if (error != B_OK)
			return error;
		fTeamNotificationsRequested = true;
	}

	// threads
	if ((fFlags & B_SYSTEM_PROFILER_THREAD_EVENTS) != 0) {
		error = notificationManager.AddListener("threads",
			THREAD_ADDED | THREAD_REMOVED, *this);
		if (error != B_OK)
			return error;
		fThreadNotificationsRequested = true;
	}

	// images
	if ((fFlags & B_SYSTEM_PROFILER_IMAGE_EVENTS) != 0) {
		error = notificationManager.AddListener("images",
			IMAGE_ADDED | IMAGE_REMOVED, *this);
		if (error != B_OK)
			return error;
		fImageNotificationsRequested = true;
	}

	// I/O events
	if ((fFlags & B_SYSTEM_PROFILER_IO_SCHEDULING_EVENTS) != 0) {
		error = notificationManager.AddListener("I/O",
			IO_SCHEDULER_ADDED | IO_SCHEDULER_REMOVED
				| IO_SCHEDULER_REQUEST_SCHEDULED | IO_SCHEDULER_REQUEST_FINISHED
				| IO_SCHEDULER_OPERATION_STARTED
				| IO_SCHEDULER_OPERATION_FINISHED,
			*this);
		if (error != B_OK)
			return error;
		fIONotificationsRequested = true;
	}

	// We need to fill the buffer with the initial state of teams, threads,
	// and images.

	// teams
	if ((fFlags & B_SYSTEM_PROFILER_TEAM_EVENTS) != 0) {
		InterruptsSpinLocker locker(fLock);

		TeamListIterator iterator;
		while (Team* team = iterator.Next()) {
			locker.Unlock();

			bool added = _TeamAdded(team);

			// release the reference returned by the iterator
			team->ReleaseReference();

			if (!added)
				return B_BUFFER_OVERFLOW;

			locker.Lock();
		}

		fTeamNotificationsEnabled = true;
	}

	// images
	if ((fFlags & B_SYSTEM_PROFILER_IMAGE_EVENTS) != 0) {
		if (image_iterate_through_images(&_InitialImageIterator, this) != NULL)
			return B_BUFFER_OVERFLOW;
	}

	// threads
	if ((fFlags & B_SYSTEM_PROFILER_THREAD_EVENTS) != 0) {
		InterruptsSpinLocker locker(fLock);

		ThreadListIterator iterator;
		while (Thread* thread = iterator.Next()) {
			locker.Unlock();

			bool added = _ThreadAdded(thread);

			// release the reference returned by the iterator
			thread->ReleaseReference();

			if (!added)
				return B_BUFFER_OVERFLOW;

			locker.Lock();
		}

		fThreadNotificationsEnabled = true;
	}

	fProfilingActive = true;

	// start scheduler and wait object listening
	if ((fFlags & B_SYSTEM_PROFILER_SCHEDULING_EVENTS) != 0) {
		scheduler_add_listener(this);
		fSchedulerNotificationsRequested = true;

		InterruptsSpinLocker waitObjectLocker(gWaitObjectListenerLock);
		add_wait_object_listener(this);
		fWaitObjectNotificationsRequested = true;
		waitObjectLocker.Unlock();

		// fake schedule events for the initially running threads
		int32 cpuCount = smp_get_num_cpus();
		for (int32 i = 0; i < cpuCount; i++) {
			Thread* thread = gCPU[i].running_thread;
			if (thread != NULL)
				ThreadScheduled(thread, thread);
		}
	}

	// I/O scheduling
	if ((fFlags & B_SYSTEM_PROFILER_IO_SCHEDULING_EVENTS) != 0) {
		IOSchedulerRoster* roster = IOSchedulerRoster::Default();
		AutoLocker<IOSchedulerRoster> rosterLocker(roster);

		for (IOSchedulerList::ConstIterator it
				= roster->SchedulerList().GetIterator();
			IOScheduler* scheduler = it.Next();) {
			_IOSchedulerAdded(scheduler);
		}

		fIONotificationsEnabled = true;
	}

	// activate the profiling timers on all CPUs
	if ((fFlags & B_SYSTEM_PROFILER_SAMPLING_EVENTS) != 0)
		call_all_cpus(_InitTimers, this);

	return B_OK;
}