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