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