xref: /haiku/headers/os/kernel/OS.h (revision 15fb7d88e971c4d6c787c6a3a5c159afb1ebf77b)
1 /*
2  * Copyright 2004-2019, Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef _OS_H
6 #define _OS_H
7 
8 /** Kernel specific structures and functions */
9 
10 #include <stdarg.h>
11 #include <sys/types.h>
12 
13 #include <SupportDefs.h>
14 #include <StorageDefs.h>
15 
16 
17 #ifdef __cplusplus
18 extern "C" {
19 #endif
20 
21 /* System constants */
22 
23 #define B_OS_NAME_LENGTH	32
24 #define B_PAGE_SIZE			4096
25 #define B_INFINITE_TIMEOUT	(9223372036854775807LL)
26 
27 enum {
28 	B_TIMEOUT						= 0x8,	/* relative timeout */
29 	B_RELATIVE_TIMEOUT				= 0x8,	/* fails after a relative timeout
30 												with B_TIMED_OUT */
31 	B_ABSOLUTE_TIMEOUT				= 0x10,	/* fails after an absolute timeout
32 												with B_TIMED_OUT */
33 
34 	/* experimental Haiku only API */
35 	B_TIMEOUT_REAL_TIME_BASE		= 0x40,
36 	B_ABSOLUTE_REAL_TIME_TIMEOUT	= B_ABSOLUTE_TIMEOUT
37 										| B_TIMEOUT_REAL_TIME_BASE
38 };
39 
40 
41 /* Types */
42 
43 typedef int32 area_id;
44 typedef int32 port_id;
45 typedef int32 sem_id;
46 typedef int32 team_id;
47 typedef int32 thread_id;
48 
49 
50 /* Areas */
51 
52 typedef struct area_info {
53 	area_id		area;
54 	char		name[B_OS_NAME_LENGTH];
55 	size_t		size;
56 	uint32		lock;
57 	uint32		protection;
58 	team_id		team;
59 	uint32		ram_size;
60 	uint32		copy_count;
61 	uint32		in_count;
62 	uint32		out_count;
63 	void		*address;
64 } area_info;
65 
66 /* area locking */
67 #define B_NO_LOCK				0
68 #define B_LAZY_LOCK				1
69 #define B_FULL_LOCK				2
70 #define B_CONTIGUOUS			3
71 #define	B_LOMEM					4	/* B_CONTIGUOUS, < 16 MB physical address */
72 #define	B_32_BIT_FULL_LOCK		5	/* B_FULL_LOCK, < 4 GB physical addresses */
73 #define	B_32_BIT_CONTIGUOUS		6	/* B_CONTIGUOUS, < 4 GB physical address */
74 
75 /* address spec for create_area(), and clone_area() */
76 #define B_ANY_ADDRESS				0
77 #define B_EXACT_ADDRESS				1
78 #define B_BASE_ADDRESS				2
79 #define B_CLONE_ADDRESS				3
80 #define	B_ANY_KERNEL_ADDRESS		4
81 /* B_ANY_KERNEL_BLOCK_ADDRESS		5 */
82 #define B_RANDOMIZED_ANY_ADDRESS	6
83 #define B_RANDOMIZED_BASE_ADDRESS	7
84 
85 /* area protection */
86 #define B_READ_AREA				(1 << 0)
87 #define B_WRITE_AREA			(1 << 1)
88 #define B_EXECUTE_AREA			(1 << 2)
89 #define B_STACK_AREA			(1 << 3)
90 	/* "stack" protection is not available on most platforms - it's used
91 	   to only commit memory as needed, and have guard pages at the
92 	   bottom of the stack. */
93 #define B_CLONEABLE_AREA		(1 << 8)
94 
95 extern area_id		create_area(const char *name, void **startAddress,
96 						uint32 addressSpec, size_t size, uint32 lock,
97 						uint32 protection);
98 extern area_id		clone_area(const char *name, void **destAddress,
99 						uint32 addressSpec, uint32 protection, area_id source);
100 extern area_id		find_area(const char *name);
101 extern area_id		area_for(void *address);
102 extern status_t		delete_area(area_id id);
103 extern status_t		resize_area(area_id id, size_t newSize);
104 extern status_t		set_area_protection(area_id id, uint32 newProtection);
105 
106 /* system private, use macros instead */
107 extern status_t		_get_area_info(area_id id, area_info *areaInfo, size_t size);
108 extern status_t		_get_next_area_info(team_id team, ssize_t *cookie,
109 						area_info *areaInfo, size_t size);
110 
111 #define get_area_info(id, areaInfo) \
112 	_get_area_info((id), (areaInfo),sizeof(*(areaInfo)))
113 #define get_next_area_info(team, cookie, areaInfo) \
114 	_get_next_area_info((team), (cookie), (areaInfo), sizeof(*(areaInfo)))
115 
116 
117 /* Ports */
118 
119 typedef struct port_info {
120 	port_id		port;
121 	team_id		team;
122 	char		name[B_OS_NAME_LENGTH];
123 	int32		capacity;		/* queue depth */
124 	int32		queue_count;	/* # msgs waiting to be read */
125 	int32		total_count;	/* total # msgs read so far */
126 } port_info;
127 
128 extern port_id		create_port(int32 capacity, const char *name);
129 extern port_id		find_port(const char *name);
130 extern ssize_t		read_port(port_id port, int32 *code, void *buffer,
131 						size_t bufferSize);
132 extern ssize_t		read_port_etc(port_id port, int32 *code, void *buffer,
133 						size_t bufferSize, uint32 flags, bigtime_t timeout);
134 extern status_t		write_port(port_id port, int32 code, const void *buffer,
135 						size_t bufferSize);
136 extern status_t		write_port_etc(port_id port, int32 code, const void *buffer,
137 						size_t bufferSize, uint32 flags, bigtime_t timeout);
138 extern status_t		close_port(port_id port);
139 extern status_t		delete_port(port_id port);
140 
141 extern ssize_t		port_buffer_size(port_id port);
142 extern ssize_t		port_buffer_size_etc(port_id port, uint32 flags,
143 						bigtime_t timeout);
144 extern ssize_t		port_count(port_id port);
145 extern status_t		set_port_owner(port_id port, team_id team);
146 
147 /* system private, use the macros instead */
148 extern status_t		_get_port_info(port_id port, port_info *portInfo,
149 						size_t portInfoSize);
150 extern status_t		_get_next_port_info(team_id team, int32 *cookie,
151 						port_info *portInfo, size_t portInfoSize);
152 
153 #define get_port_info(port, info) \
154 	_get_port_info((port), (info), sizeof(*(info)))
155 #define get_next_port_info(team, cookie, info) \
156 	_get_next_port_info((team), (cookie), (info), sizeof(*(info)))
157 
158 
159 /* WARNING: The following is Haiku experimental API. It might be removed or
160    changed in the future. */
161 
162 typedef struct port_message_info {
163 	size_t		size;
164 	uid_t		sender;
165 	gid_t		sender_group;
166 	team_id		sender_team;
167 } port_message_info;
168 
169 /* similar to port_buffer_size_etc(), but returns (more) info */
170 extern status_t		_get_port_message_info_etc(port_id port,
171 						port_message_info *info, size_t infoSize, uint32 flags,
172 						bigtime_t timeout);
173 
174 #define get_port_message_info_etc(port, info, flags, timeout) \
175 	_get_port_message_info_etc((port), (info), sizeof(*(info)), flags, timeout)
176 
177 
178 /* Semaphores */
179 
180 typedef struct sem_info {
181 	sem_id		sem;
182 	team_id		team;
183 	char		name[B_OS_NAME_LENGTH];
184 	int32		count;
185 	thread_id	latest_holder;
186 } sem_info;
187 
188 /* semaphore flags */
189 enum {
190 	B_CAN_INTERRUPT				= 0x01,	/* acquisition of the semaphore can be
191 										   interrupted (system use only) */
192 	B_CHECK_PERMISSION			= 0x04,	/* ownership will be checked (system use
193 										   only) */
194 	B_KILL_CAN_INTERRUPT		= 0x20,	/* acquisition of the semaphore can be
195 										   interrupted by SIGKILL[THR], even
196 										   if not B_CAN_INTERRUPT (system use
197 										   only) */
198 
199 	/* release_sem_etc() only flags */
200 	B_DO_NOT_RESCHEDULE			= 0x02,	/* thread is not rescheduled */
201 	B_RELEASE_ALL				= 0x08,	/* all waiting threads will be woken up,
202 										   count will be zeroed */
203 	B_RELEASE_IF_WAITING_ONLY	= 0x10	/* release count only if there are any
204 										   threads waiting */
205 };
206 
207 extern sem_id		create_sem(int32 count, const char *name);
208 extern status_t		delete_sem(sem_id id);
209 extern status_t		acquire_sem(sem_id id);
210 extern status_t		acquire_sem_etc(sem_id id, int32 count, uint32 flags,
211 						bigtime_t timeout);
212 extern status_t		release_sem(sem_id id);
213 extern status_t		release_sem_etc(sem_id id, int32 count, uint32 flags);
214 /* TODO: the following two calls are not part of the BeOS API, and might be
215    changed or even removed for the final release of Haiku R1 */
216 extern status_t		switch_sem(sem_id semToBeReleased, sem_id id);
217 extern status_t		switch_sem_etc(sem_id semToBeReleased, sem_id id,
218 						int32 count, uint32 flags, bigtime_t timeout);
219 extern status_t		get_sem_count(sem_id id, int32 *threadCount);
220 extern status_t		set_sem_owner(sem_id id, team_id team);
221 
222 /* system private, use the macros instead */
223 extern status_t		_get_sem_info(sem_id id, struct sem_info *info,
224 						size_t infoSize);
225 extern status_t		_get_next_sem_info(team_id team, int32 *cookie,
226 						struct sem_info *info, size_t infoSize);
227 
228 #define get_sem_info(sem, info) \
229 	_get_sem_info((sem), (info), sizeof(*(info)))
230 
231 #define get_next_sem_info(team, cookie, info) \
232 	_get_next_sem_info((team), (cookie), (info), sizeof(*(info)))
233 
234 
235 /* Teams */
236 
237 typedef struct {
238 	team_id			team;
239 	int32			thread_count;
240 	int32			image_count;
241 	int32			area_count;
242 	thread_id		debugger_nub_thread;
243 	port_id			debugger_nub_port;
244 	int32			argc;
245 	char			args[64];
246 	uid_t			uid;
247 	gid_t			gid;
248 } team_info;
249 
250 #define B_CURRENT_TEAM	0
251 #define B_SYSTEM_TEAM	1
252 
253 extern status_t		kill_team(team_id team);
254 	/* see also: send_signal() */
255 
256 /* system private, use macros instead */
257 extern status_t		_get_team_info(team_id id, team_info *info, size_t size);
258 extern status_t		_get_next_team_info(int32 *cookie, team_info *info,
259 						size_t size);
260 
261 #define get_team_info(id, info) \
262 	_get_team_info((id), (info), sizeof(*(info)))
263 
264 #define get_next_team_info(cookie, info) \
265 	_get_next_team_info((cookie), (info), sizeof(*(info)))
266 
267 /* team usage info */
268 
269 typedef struct {
270 	bigtime_t		user_time;
271 	bigtime_t		kernel_time;
272 } team_usage_info;
273 
274 enum {
275 	/* compatible to sys/resource.h RUSAGE_SELF and RUSAGE_CHILDREN */
276 	B_TEAM_USAGE_SELF		= 0,
277 	B_TEAM_USAGE_CHILDREN	= -1
278 };
279 
280 /* system private, use macros instead */
281 extern status_t		_get_team_usage_info(team_id team, int32 who,
282 						team_usage_info *info, size_t size);
283 
284 #define get_team_usage_info(team, who, info) \
285 	_get_team_usage_info((team), (who), (info), sizeof(*(info)))
286 
287 
288 /* Threads */
289 
290 typedef enum {
291 	B_THREAD_RUNNING	= 1,
292 	B_THREAD_READY,
293 	B_THREAD_RECEIVING,
294 	B_THREAD_ASLEEP,
295 	B_THREAD_SUSPENDED,
296 	B_THREAD_WAITING
297 } thread_state;
298 
299 typedef struct {
300 	thread_id		thread;
301 	team_id			team;
302 	char			name[B_OS_NAME_LENGTH];
303 	thread_state	state;
304 	int32			priority;
305 	sem_id			sem;
306 	bigtime_t		user_time;
307 	bigtime_t		kernel_time;
308 	void			*stack_base;
309 	void			*stack_end;
310 } thread_info;
311 
312 #define B_IDLE_PRIORITY					0
313 #define B_LOWEST_ACTIVE_PRIORITY		1
314 #define B_LOW_PRIORITY					5
315 #define B_NORMAL_PRIORITY				10
316 #define B_DISPLAY_PRIORITY				15
317 #define	B_URGENT_DISPLAY_PRIORITY		20
318 #define	B_REAL_TIME_DISPLAY_PRIORITY	100
319 #define	B_URGENT_PRIORITY				110
320 #define B_REAL_TIME_PRIORITY			120
321 
322 #define B_SYSTEM_TIMEBASE				0
323 	/* time base for snooze_*(), compatible with the clockid_t constants defined
324 	   in <time.h> */
325 
326 #define B_FIRST_REAL_TIME_PRIORITY		B_REAL_TIME_DISPLAY_PRIORITY
327 
328 typedef status_t (*thread_func)(void *);
329 #define thread_entry thread_func
330 	/* thread_entry is for backward compatibility only! Use thread_func */
331 
332 extern thread_id	spawn_thread(thread_func, const char *name, int32 priority,
333 						void *data);
334 extern status_t		kill_thread(thread_id thread);
335 extern status_t		resume_thread(thread_id thread);
336 extern status_t		suspend_thread(thread_id thread);
337 
338 extern status_t		rename_thread(thread_id thread, const char *newName);
339 extern status_t		set_thread_priority(thread_id thread, int32 newPriority);
340 extern void			exit_thread(status_t status);
341 extern status_t		wait_for_thread(thread_id thread, status_t *returnValue);
342 extern status_t		on_exit_thread(void (*callback)(void *), void *data);
343 
344 extern thread_id 	find_thread(const char *name);
345 
346 extern status_t		send_data(thread_id thread, int32 code, const void *buffer,
347 						size_t bufferSize);
348 extern int32		receive_data(thread_id *sender, void *buffer,
349 						size_t bufferSize);
350 extern bool			has_data(thread_id thread);
351 
352 extern status_t		snooze(bigtime_t amount);
353 extern status_t		snooze_etc(bigtime_t amount, int timeBase, uint32 flags);
354 extern status_t		snooze_until(bigtime_t time, int timeBase);
355 
356 /* system private, use macros instead */
357 extern status_t		_get_thread_info(thread_id id, thread_info *info, size_t size);
358 extern status_t		_get_next_thread_info(team_id team, int32 *cookie,
359 						thread_info *info, size_t size);
360 
361 #define get_thread_info(id, info) \
362 	_get_thread_info((id), (info), sizeof(*(info)))
363 
364 #define get_next_thread_info(team, cookie, info) \
365 	_get_next_thread_info((team), (cookie), (info), sizeof(*(info)))
366 
367 /* bridge to the pthread API */
368 extern thread_id	get_pthread_thread_id(pthread_t thread);
369 /* TODO: Would be nice to have, but we use TLS to associate a thread with its
370    pthread object. So this is not trivial to implement.
371 extern status_t		convert_to_pthread(thread_id thread, pthread_t *_thread);
372 */
373 
374 
375 /* Time */
376 
377 extern unsigned long real_time_clock(void);
378 extern void			set_real_time_clock(unsigned long secsSinceJan1st1970);
379 extern bigtime_t	real_time_clock_usecs(void);
380 extern bigtime_t	system_time(void);
381 						/* time since booting in microseconds */
382 extern nanotime_t	system_time_nsecs(void);
383 						/* time since booting in nanoseconds */
384 
385 					/* deprecated (is no-op) */
386 extern status_t		set_timezone(const char *timezone);
387 
388 /* Alarm */
389 
390 enum {
391 	B_ONE_SHOT_ABSOLUTE_ALARM	= 1,
392 	B_ONE_SHOT_RELATIVE_ALARM,
393 	B_PERIODIC_ALARM			/* "when" specifies the period */
394 };
395 
396 extern bigtime_t	set_alarm(bigtime_t when, uint32 flags);
397 
398 
399 /* Debugger */
400 
401 extern void			debugger(const char *message);
402 
403 /*
404    calling this function with a non-zero value will cause your thread
405    to receive signals for any exceptional conditions that occur (i.e.
406    you'll get SIGSEGV for data access exceptions, SIGFPE for floating
407    point errors, SIGILL for illegal instructions, etc).
408 
409    to re-enable the default debugger pass a zero.
410 */
411 extern int			disable_debugger(int state);
412 
413 /* TODO: Remove. Temporary debug helper. */
414 extern void			debug_printf(const char *format, ...)
415 						__attribute__ ((format (__printf__, 1, 2)));
416 extern void			debug_vprintf(const char *format, va_list args);
417 extern void			ktrace_printf(const char *format, ...)
418 						__attribute__ ((format (__printf__, 1, 2)));
419 extern void			ktrace_vprintf(const char *format, va_list args);
420 
421 
422 /* System information */
423 
424 typedef struct {
425 	bigtime_t	active_time;	/* usec of doing useful work since boot */
426 	bool		enabled;
427 } cpu_info;
428 
429 typedef struct {
430 	bigtime_t		boot_time;			/* time of boot (usecs since 1/1/1970) */
431 
432 	uint32			cpu_count;			/* number of cpus */
433 
434 	uint64			max_pages;			/* total # of accessible pages */
435 	uint64			used_pages;			/* # of accessible pages in use */
436 	uint64			cached_pages;
437 	uint64			block_cache_pages;
438 	uint64			ignored_pages;		/* # of ignored/inaccessible pages */
439 
440 	uint64			needed_memory;
441 	uint64			free_memory;
442 
443 	uint64			max_swap_pages;
444 	uint64			free_swap_pages;
445 
446 	uint32			page_faults;		/* # of page faults */
447 
448 	uint32			max_sems;
449 	uint32			used_sems;
450 
451 	uint32			max_ports;
452 	uint32			used_ports;
453 
454 	uint32			max_threads;
455 	uint32			used_threads;
456 
457 	uint32			max_teams;
458 	uint32			used_teams;
459 
460 	char			kernel_name[B_FILE_NAME_LENGTH];
461 	char			kernel_build_date[B_OS_NAME_LENGTH];
462 	char			kernel_build_time[B_OS_NAME_LENGTH];
463 
464 	int64			kernel_version;
465 	uint32			abi;				/* the system API */
466 } system_info;
467 
468 enum topology_level_type {
469 	B_TOPOLOGY_UNKNOWN,
470 	B_TOPOLOGY_ROOT,
471 	B_TOPOLOGY_SMT,
472 	B_TOPOLOGY_CORE,
473 	B_TOPOLOGY_PACKAGE
474 };
475 
476 enum cpu_platform {
477 	B_CPU_UNKNOWN,
478 	B_CPU_x86,
479 	B_CPU_x86_64,
480 	B_CPU_PPC,
481 	B_CPU_PPC_64,
482 	B_CPU_M68K,
483 	B_CPU_ARM,
484 	B_CPU_ARM_64,
485 	B_CPU_ALPHA,
486 	B_CPU_MIPS,
487 	B_CPU_SH
488 };
489 
490 enum cpu_vendor {
491 	B_CPU_VENDOR_UNKNOWN,
492 	B_CPU_VENDOR_AMD,
493 	B_CPU_VENDOR_CYRIX,
494 	B_CPU_VENDOR_IDT,
495 	B_CPU_VENDOR_INTEL,
496 	B_CPU_VENDOR_NATIONAL_SEMICONDUCTOR,
497 	B_CPU_VENDOR_RISE,
498 	B_CPU_VENDOR_TRANSMETA,
499 	B_CPU_VENDOR_VIA,
500 	B_CPU_VENDOR_IBM,
501 	B_CPU_VENDOR_MOTOROLA,
502 	B_CPU_VENDOR_NEC
503 };
504 
505 typedef struct {
506 	enum cpu_platform		platform;
507 } cpu_topology_root_info;
508 
509 typedef struct {
510 	enum cpu_vendor			vendor;
511 	uint32					cache_line_size;
512 } cpu_topology_package_info;
513 
514 typedef struct {
515 	uint32					model;
516 	uint64					default_frequency;
517 } cpu_topology_core_info;
518 
519 typedef struct {
520 	uint32							id;
521 	enum topology_level_type		type;
522 	uint32							level;
523 
524 	union {
525 		cpu_topology_root_info		root;
526 		cpu_topology_package_info	package;
527 		cpu_topology_core_info		core;
528 	} data;
529 } cpu_topology_node_info;
530 
531 
532 extern status_t		get_system_info(system_info* info);
533 extern status_t		get_cpu_info(uint32 firstCPU, uint32 cpuCount,
534 						cpu_info* info);
535 extern status_t		get_cpu_topology_info(cpu_topology_node_info* topologyInfos,
536 						uint32* topologyInfoCount);
537 
538 #if defined(__i386__) || defined(__x86_64__)
539 typedef union {
540 	struct {
541 		uint32	max_eax;
542 		char	vendor_id[12];
543 	} eax_0;
544 
545 	struct {
546 		uint32	stepping		: 4;
547 		uint32	model			: 4;
548 		uint32	family			: 4;
549 		uint32	type			: 2;
550 		uint32	reserved_0		: 2;
551 		uint32	extended_model	: 4;
552 		uint32	extended_family	: 8;
553 		uint32	reserved_1		: 4;
554 
555 		uint32	brand_index		: 8;
556 		uint32	clflush			: 8;
557 		uint32	logical_cpus	: 8;
558 		uint32	apic_id			: 8;
559 
560 		uint32	features;
561 		uint32	extended_features;
562 	} eax_1;
563 
564 	struct {
565 		uint8	call_num;
566 		uint8	cache_descriptors[15];
567 	} eax_2;
568 
569 	struct {
570 		uint32	reserved[2];
571 		uint32	serial_number_high;
572 		uint32	serial_number_low;
573 	} eax_3;
574 
575 	char		as_chars[16];
576 
577 	struct {
578 		uint32	eax;
579 		uint32	ebx;
580 		uint32	edx;
581 		uint32	ecx;
582 	} regs;
583 } cpuid_info;
584 
585 extern status_t		get_cpuid(cpuid_info *info, uint32 eaxRegister,
586 						uint32 cpuNum);
587 #endif
588 
589 
590 extern int32		is_computer_on(void);
591 extern double		is_computer_on_fire(void);
592 
593 
594 /* signal related functions */
595 int		send_signal(thread_id threadID, unsigned int signal);
596 void	set_signal_stack(void* base, size_t size);
597 
598 
599 /* WARNING: Experimental API! */
600 
601 enum {
602 	B_OBJECT_TYPE_FD		= 0,
603 	B_OBJECT_TYPE_SEMAPHORE	= 1,
604 	B_OBJECT_TYPE_PORT		= 2,
605 	B_OBJECT_TYPE_THREAD	= 3
606 };
607 
608 enum {
609 	B_EVENT_READ				= 0x0001,	/* FD/port readable */
610 	B_EVENT_WRITE				= 0x0002,	/* FD/port writable */
611 	B_EVENT_ERROR				= 0x0004,	/* FD error */
612 	B_EVENT_PRIORITY_READ		= 0x0008,	/* FD priority readable */
613 	B_EVENT_PRIORITY_WRITE		= 0x0010,	/* FD priority writable */
614 	B_EVENT_HIGH_PRIORITY_READ	= 0x0020,	/* FD high priority readable */
615 	B_EVENT_HIGH_PRIORITY_WRITE	= 0x0040,	/* FD high priority writable */
616 	B_EVENT_DISCONNECTED		= 0x0080,	/* FD disconnected */
617 
618 	B_EVENT_ACQUIRE_SEMAPHORE	= 0x0001,	/* semaphore can be acquired */
619 
620 	B_EVENT_INVALID				= 0x1000	/* FD/port/sem/thread ID not or
621 											   no longer valid (e.g. has been
622 											   close/deleted) */
623 };
624 
625 typedef struct object_wait_info {
626 	int32		object;						/* ID of the object */
627 	uint16		type;						/* type of the object */
628 	uint16		events;						/* events mask */
629 } object_wait_info;
630 
631 /* wait_for_objects[_etc]() waits until at least one of the specified events or,
632    if given, the timeout occurred. When entering the function the
633    object_wait_info::events field specifies the events for each object the
634    caller is interested in. When the function returns the fields reflect the
635    events that actually occurred. The events B_EVENT_INVALID, B_EVENT_ERROR,
636    and B_EVENT_DISCONNECTED don't need to be specified. They will always be
637    reported, when they occur. */
638 
639 extern ssize_t		wait_for_objects(object_wait_info* infos, int numInfos);
640 extern ssize_t		wait_for_objects_etc(object_wait_info* infos, int numInfos,
641 						uint32 flags, bigtime_t timeout);
642 
643 
644 #ifdef __cplusplus
645 }
646 #endif
647 
648 #endif /* _OS_H */
649