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 } team_info; 251 252 #define B_CURRENT_TEAM 0 253 #define B_SYSTEM_TEAM 1 254 255 extern status_t kill_team(team_id team); 256 /* see also: send_signal() */ 257 258 /* system private, use macros instead */ 259 extern status_t _get_team_info(team_id id, team_info *info, size_t size); 260 extern status_t _get_next_team_info(int32 *cookie, team_info *info, 261 size_t size); 262 263 #define get_team_info(id, info) \ 264 _get_team_info((id), (info), sizeof(*(info))) 265 266 #define get_next_team_info(cookie, info) \ 267 _get_next_team_info((cookie), (info), sizeof(*(info))) 268 269 /* team usage info */ 270 271 typedef struct { 272 bigtime_t user_time; 273 bigtime_t kernel_time; 274 } team_usage_info; 275 276 enum { 277 /* compatible to sys/resource.h RUSAGE_SELF and RUSAGE_CHILDREN */ 278 B_TEAM_USAGE_SELF = 0, 279 B_TEAM_USAGE_CHILDREN = -1 280 }; 281 282 /* system private, use macros instead */ 283 extern status_t _get_team_usage_info(team_id team, int32 who, 284 team_usage_info *info, size_t size); 285 286 #define get_team_usage_info(team, who, info) \ 287 _get_team_usage_info((team), (who), (info), sizeof(*(info))) 288 289 290 /* Threads */ 291 292 typedef enum { 293 B_THREAD_RUNNING = 1, 294 B_THREAD_READY, 295 B_THREAD_RECEIVING, 296 B_THREAD_ASLEEP, 297 B_THREAD_SUSPENDED, 298 B_THREAD_WAITING 299 } thread_state; 300 301 typedef struct { 302 thread_id thread; 303 team_id team; 304 char name[B_OS_NAME_LENGTH]; 305 thread_state state; 306 int32 priority; 307 sem_id sem; 308 bigtime_t user_time; 309 bigtime_t kernel_time; 310 void *stack_base; 311 void *stack_end; 312 } thread_info; 313 314 #define B_IDLE_PRIORITY 0 315 #define B_LOWEST_ACTIVE_PRIORITY 1 316 #define B_LOW_PRIORITY 5 317 #define B_NORMAL_PRIORITY 10 318 #define B_DISPLAY_PRIORITY 15 319 #define B_URGENT_DISPLAY_PRIORITY 20 320 #define B_REAL_TIME_DISPLAY_PRIORITY 100 321 #define B_URGENT_PRIORITY 110 322 #define B_REAL_TIME_PRIORITY 120 323 324 #define B_SYSTEM_TIMEBASE 0 325 /* time base for snooze_*(), compatible with the clockid_t constants defined 326 in <time.h> */ 327 328 #define B_FIRST_REAL_TIME_PRIORITY B_REAL_TIME_DISPLAY_PRIORITY 329 330 typedef status_t (*thread_func)(void *); 331 #define thread_entry thread_func 332 /* thread_entry is for backward compatibility only! Use thread_func */ 333 334 extern thread_id spawn_thread(thread_func, const char *name, int32 priority, 335 void *data); 336 extern status_t kill_thread(thread_id thread); 337 extern status_t resume_thread(thread_id thread); 338 extern status_t suspend_thread(thread_id thread); 339 340 extern status_t rename_thread(thread_id thread, const char *newName); 341 extern status_t set_thread_priority(thread_id thread, int32 newPriority); 342 extern void exit_thread(status_t status); 343 extern status_t wait_for_thread(thread_id thread, status_t *returnValue); 344 extern status_t on_exit_thread(void (*callback)(void *), void *data); 345 346 extern thread_id find_thread(const char *name); 347 348 extern status_t send_data(thread_id thread, int32 code, const void *buffer, 349 size_t bufferSize); 350 extern int32 receive_data(thread_id *sender, void *buffer, 351 size_t bufferSize); 352 extern bool has_data(thread_id thread); 353 354 extern status_t snooze(bigtime_t amount); 355 extern status_t snooze_etc(bigtime_t amount, int timeBase, uint32 flags); 356 extern status_t snooze_until(bigtime_t time, int timeBase); 357 358 /* system private, use macros instead */ 359 extern status_t _get_thread_info(thread_id id, thread_info *info, size_t size); 360 extern status_t _get_next_thread_info(team_id team, int32 *cookie, 361 thread_info *info, size_t size); 362 363 #define get_thread_info(id, info) \ 364 _get_thread_info((id), (info), sizeof(*(info))) 365 366 #define get_next_thread_info(team, cookie, info) \ 367 _get_next_thread_info((team), (cookie), (info), sizeof(*(info))) 368 369 /* bridge to the pthread API */ 370 extern thread_id get_pthread_thread_id(pthread_t thread); 371 /* TODO: Would be nice to have, but we use TLS to associate a thread with its 372 pthread object. So this is not trivial to implement. 373 extern status_t convert_to_pthread(thread_id thread, pthread_t *_thread); 374 */ 375 376 377 /* Time */ 378 379 extern unsigned long real_time_clock(void); 380 extern void set_real_time_clock(unsigned long secsSinceJan1st1970); 381 extern bigtime_t real_time_clock_usecs(void); 382 extern bigtime_t system_time(void); 383 /* time since booting in microseconds */ 384 extern nanotime_t system_time_nsecs(void); 385 /* time since booting in nanoseconds */ 386 387 /* deprecated (is no-op) */ 388 extern status_t set_timezone(const char *timezone); 389 390 /* Alarm */ 391 392 enum { 393 B_ONE_SHOT_ABSOLUTE_ALARM = 1, 394 B_ONE_SHOT_RELATIVE_ALARM, 395 B_PERIODIC_ALARM /* "when" specifies the period */ 396 }; 397 398 extern bigtime_t set_alarm(bigtime_t when, uint32 flags); 399 400 401 /* Debugger */ 402 403 extern void debugger(const char *message); 404 405 /* 406 calling this function with a non-zero value will cause your thread 407 to receive signals for any exceptional conditions that occur (i.e. 408 you'll get SIGSEGV for data access exceptions, SIGFPE for floating 409 point errors, SIGILL for illegal instructions, etc). 410 411 to re-enable the default debugger pass a zero. 412 */ 413 extern int disable_debugger(int state); 414 415 /* TODO: Remove. Temporary debug helper. */ 416 extern void debug_printf(const char *format, ...) 417 __attribute__ ((format (__printf__, 1, 2))); 418 extern void debug_vprintf(const char *format, va_list args); 419 extern void ktrace_printf(const char *format, ...) 420 __attribute__ ((format (__printf__, 1, 2))); 421 extern void ktrace_vprintf(const char *format, va_list args); 422 423 424 /* System information */ 425 426 typedef struct { 427 bigtime_t active_time; /* usec of doing useful work since boot */ 428 bool enabled; 429 } cpu_info; 430 431 typedef struct { 432 bigtime_t boot_time; /* time of boot (usecs since 1/1/1970) */ 433 434 uint32 cpu_count; /* number of cpus */ 435 436 uint64 max_pages; /* total # of accessible pages */ 437 uint64 used_pages; /* # of accessible pages in use */ 438 uint64 cached_pages; 439 uint64 block_cache_pages; 440 uint64 ignored_pages; /* # of ignored/inaccessible pages */ 441 442 uint64 needed_memory; 443 uint64 free_memory; 444 445 uint64 max_swap_pages; 446 uint64 free_swap_pages; 447 448 uint32 page_faults; /* # of page faults */ 449 450 uint32 max_sems; 451 uint32 used_sems; 452 453 uint32 max_ports; 454 uint32 used_ports; 455 456 uint32 max_threads; 457 uint32 used_threads; 458 459 uint32 max_teams; 460 uint32 used_teams; 461 462 char kernel_name[B_FILE_NAME_LENGTH]; 463 char kernel_build_date[B_OS_NAME_LENGTH]; 464 char kernel_build_time[B_OS_NAME_LENGTH]; 465 466 int64 kernel_version; 467 uint32 abi; /* the system API */ 468 } system_info; 469 470 enum topology_level_type { 471 B_TOPOLOGY_UNKNOWN, 472 B_TOPOLOGY_ROOT, 473 B_TOPOLOGY_SMT, 474 B_TOPOLOGY_CORE, 475 B_TOPOLOGY_PACKAGE 476 }; 477 478 enum cpu_platform { 479 B_CPU_UNKNOWN, 480 B_CPU_x86, 481 B_CPU_x86_64, 482 B_CPU_PPC, 483 B_CPU_PPC_64, 484 B_CPU_M68K, 485 B_CPU_ARM, 486 B_CPU_ARM_64, 487 B_CPU_ALPHA, 488 B_CPU_MIPS, 489 B_CPU_SH, 490 B_CPU_SPARC, 491 B_CPU_RISC_V 492 }; 493 494 enum cpu_vendor { 495 B_CPU_VENDOR_UNKNOWN, 496 B_CPU_VENDOR_AMD, 497 B_CPU_VENDOR_CYRIX, 498 B_CPU_VENDOR_IDT, 499 B_CPU_VENDOR_INTEL, 500 B_CPU_VENDOR_NATIONAL_SEMICONDUCTOR, 501 B_CPU_VENDOR_RISE, 502 B_CPU_VENDOR_TRANSMETA, 503 B_CPU_VENDOR_VIA, 504 B_CPU_VENDOR_IBM, 505 B_CPU_VENDOR_MOTOROLA, 506 B_CPU_VENDOR_NEC, 507 B_CPU_VENDOR_HYGON, 508 B_CPU_VENDOR_SUN, 509 B_CPU_VENDOR_FUJITSU 510 }; 511 512 typedef struct { 513 enum cpu_platform platform; 514 } cpu_topology_root_info; 515 516 typedef struct { 517 enum cpu_vendor vendor; 518 uint32 cache_line_size; 519 } cpu_topology_package_info; 520 521 typedef struct { 522 uint32 model; 523 uint64 default_frequency; 524 } cpu_topology_core_info; 525 526 typedef struct { 527 uint32 id; 528 enum topology_level_type type; 529 uint32 level; 530 531 union { 532 cpu_topology_root_info root; 533 cpu_topology_package_info package; 534 cpu_topology_core_info core; 535 } data; 536 } cpu_topology_node_info; 537 538 539 extern status_t get_system_info(system_info* info); 540 extern status_t get_cpu_info(uint32 firstCPU, uint32 cpuCount, 541 cpu_info* info); 542 extern status_t get_cpu_topology_info(cpu_topology_node_info* topologyInfos, 543 uint32* topologyInfoCount); 544 545 #if defined(__i386__) || defined(__x86_64__) 546 typedef union { 547 struct { 548 uint32 max_eax; 549 char vendor_id[12]; 550 } eax_0; 551 552 struct { 553 uint32 stepping : 4; 554 uint32 model : 4; 555 uint32 family : 4; 556 uint32 type : 2; 557 uint32 reserved_0 : 2; 558 uint32 extended_model : 4; 559 uint32 extended_family : 8; 560 uint32 reserved_1 : 4; 561 562 uint32 brand_index : 8; 563 uint32 clflush : 8; 564 uint32 logical_cpus : 8; 565 uint32 apic_id : 8; 566 567 uint32 features; 568 uint32 extended_features; 569 } eax_1; 570 571 struct { 572 uint8 call_num; 573 uint8 cache_descriptors[15]; 574 } eax_2; 575 576 struct { 577 uint32 reserved[2]; 578 uint32 serial_number_high; 579 uint32 serial_number_low; 580 } eax_3; 581 582 char as_chars[16]; 583 584 struct { 585 uint32 eax; 586 uint32 ebx; 587 uint32 edx; 588 uint32 ecx; 589 } regs; 590 } cpuid_info; 591 592 extern status_t get_cpuid(cpuid_info *info, uint32 eaxRegister, 593 uint32 cpuNum); 594 #endif 595 596 597 extern int32 is_computer_on(void); 598 extern double is_computer_on_fire(void); 599 600 601 /* signal related functions */ 602 int send_signal(thread_id threadID, unsigned int signal); 603 void set_signal_stack(void* base, size_t size); 604 605 606 /* WARNING: Experimental API! */ 607 608 enum { 609 B_OBJECT_TYPE_FD = 0, 610 B_OBJECT_TYPE_SEMAPHORE = 1, 611 B_OBJECT_TYPE_PORT = 2, 612 B_OBJECT_TYPE_THREAD = 3 613 }; 614 615 enum { 616 B_EVENT_READ = 0x0001, /* FD/port readable */ 617 B_EVENT_WRITE = 0x0002, /* FD/port writable */ 618 B_EVENT_ERROR = 0x0004, /* FD error */ 619 B_EVENT_PRIORITY_READ = 0x0008, /* FD priority readable */ 620 B_EVENT_PRIORITY_WRITE = 0x0010, /* FD priority writable */ 621 B_EVENT_HIGH_PRIORITY_READ = 0x0020, /* FD high priority readable */ 622 B_EVENT_HIGH_PRIORITY_WRITE = 0x0040, /* FD high priority writable */ 623 B_EVENT_DISCONNECTED = 0x0080, /* FD disconnected */ 624 625 B_EVENT_ACQUIRE_SEMAPHORE = 0x0001, /* semaphore can be acquired */ 626 627 B_EVENT_INVALID = 0x1000 /* FD/port/sem/thread ID not or 628 no longer valid (e.g. has been 629 close/deleted) */ 630 }; 631 632 typedef struct object_wait_info { 633 int32 object; /* ID of the object */ 634 uint16 type; /* type of the object */ 635 uint16 events; /* events mask */ 636 } object_wait_info; 637 638 /* wait_for_objects[_etc]() waits until at least one of the specified events or, 639 if given, the timeout occurred. When entering the function the 640 object_wait_info::events field specifies the events for each object the 641 caller is interested in. When the function returns the fields reflect the 642 events that actually occurred. The events B_EVENT_INVALID, B_EVENT_ERROR, 643 and B_EVENT_DISCONNECTED don't need to be specified. They will always be 644 reported, when they occur. */ 645 646 extern ssize_t wait_for_objects(object_wait_info* infos, int numInfos); 647 extern ssize_t wait_for_objects_etc(object_wait_info* infos, int numInfos, 648 uint32 flags, bigtime_t timeout); 649 650 651 #ifdef __cplusplus 652 } 653 #endif 654 655 #endif /* _OS_H */ 656