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