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