Merge pull request #3230 from avanspector/haiku

Add Haiku OS support
This commit is contained in:
gingerBill
2024-03-08 11:15:13 +00:00
committed by GitHub
31 changed files with 2515 additions and 495 deletions
+239
View File
@@ -0,0 +1,239 @@
//+build haiku
package sys_haiku
import "core:c"
Errno :: enum c.int {
// Error baselines
GENERAL_ERROR_BASE = min(c.int),
OS_ERROR_BASE = GENERAL_ERROR_BASE + 0x1000,
APP_ERROR_BASE = GENERAL_ERROR_BASE + 0x2000,
INTERFACE_ERROR_BASE = GENERAL_ERROR_BASE + 0x3000,
MEDIA_ERROR_BASE = GENERAL_ERROR_BASE + 0x4000,
TRANSLATION_ERROR_BASE = GENERAL_ERROR_BASE + 0x4800,
MIDI_ERROR_BASE = GENERAL_ERROR_BASE + 0x5000,
STORAGE_ERROR_BASE = GENERAL_ERROR_BASE + 0x6000,
POSIX_ERROR_BASE = GENERAL_ERROR_BASE + 0x7000,
MAIL_ERROR_BASE = GENERAL_ERROR_BASE + 0x8000,
PRINT_ERROR_BASE = GENERAL_ERROR_BASE + 0x9000,
DEVICE_ERROR_BASE = GENERAL_ERROR_BASE + 0xa000,
// Developer-defined errors start at (ERRORS_END+1)
ERRORS_END = GENERAL_ERROR_BASE + 0xffff,
// General Errors
NO_MEMORY = GENERAL_ERROR_BASE + 0,
IO_ERROR = GENERAL_ERROR_BASE + 1,
PERMISSION_DENIED = GENERAL_ERROR_BASE + 2,
BAD_INDEX = GENERAL_ERROR_BASE + 3,
BAD_TYPE = GENERAL_ERROR_BASE + 4,
BAD_VALUE = GENERAL_ERROR_BASE + 5,
MISMATCHED_VALUES = GENERAL_ERROR_BASE + 6,
NAME_NOT_FOUND = GENERAL_ERROR_BASE + 7,
NAME_IN_USE = GENERAL_ERROR_BASE + 8,
TIMED_OUT = GENERAL_ERROR_BASE + 9,
INTERRUPTED = GENERAL_ERROR_BASE + 10,
WOULD_BLOCK = GENERAL_ERROR_BASE + 11,
CANCELED = GENERAL_ERROR_BASE + 12,
NO_INIT = GENERAL_ERROR_BASE + 13,
NOT_INITIALIZED = GENERAL_ERROR_BASE + 13,
BUSY = GENERAL_ERROR_BASE + 14,
NOT_ALLOWED = GENERAL_ERROR_BASE + 15,
BAD_DATA = GENERAL_ERROR_BASE + 16,
DONT_DO_THAT = GENERAL_ERROR_BASE + 17,
ERROR = -1,
OK = 0,
NO_ERROR = 0,
// Kernel Kit Errors
BAD_SEM_ID = OS_ERROR_BASE + 0,
NO_MORE_SEMS = OS_ERROR_BASE + 1,
BAD_THREAD_ID = OS_ERROR_BASE + 0x100,
NO_MORE_THREADS = OS_ERROR_BASE + 0x101,
BAD_THREAD_STATE = OS_ERROR_BASE + 0x102,
BAD_TEAM_ID = OS_ERROR_BASE + 0x103,
NO_MORE_TEAMS = OS_ERROR_BASE + 0x104,
BAD_PORT_ID = OS_ERROR_BASE + 0x200,
NO_MORE_PORTS = OS_ERROR_BASE + 0x201,
BAD_IMAGE_ID = OS_ERROR_BASE + 0x300,
BAD_ADDRESS = OS_ERROR_BASE + 0x301,
NOT_AN_EXECUTABLE = OS_ERROR_BASE + 0x302,
MISSING_LIBRARY = OS_ERROR_BASE + 0x303,
MISSING_SYMBOL = OS_ERROR_BASE + 0x304,
UNKNOWN_EXECUTABLE = OS_ERROR_BASE + 0x305,
LEGACY_EXECUTABLE = OS_ERROR_BASE + 0x306,
DEBUGGER_ALREADY_INSTALLED = OS_ERROR_BASE + 0x400,
// Application Kit Errors
BAD_REPLY = APP_ERROR_BASE + 0,
DUPLICATE_REPLY = APP_ERROR_BASE + 1,
MESSAGE_TO_SELF = APP_ERROR_BASE + 2,
BAD_HANDLER = APP_ERROR_BASE + 3,
ALREADY_RUNNING = APP_ERROR_BASE + 4,
LAUNCH_FAILED = APP_ERROR_BASE + 5,
AMBIGUOUS_APP_LAUNCH = APP_ERROR_BASE + 6,
UNKNOWN_MIME_TYPE = APP_ERROR_BASE + 7,
BAD_SCRIPT_SYNTAX = APP_ERROR_BASE + 8,
LAUNCH_FAILED_NO_RESOLVE_LINK = APP_ERROR_BASE + 9,
LAUNCH_FAILED_EXECUTABLE = APP_ERROR_BASE + 10,
LAUNCH_FAILED_APP_NOT_FOUND = APP_ERROR_BASE + 11,
LAUNCH_FAILED_APP_IN_TRASH = APP_ERROR_BASE + 12,
LAUNCH_FAILED_NO_PREFERRED_APP = APP_ERROR_BASE + 13,
LAUNCH_FAILED_FILES_APP_NOT_FOUND = APP_ERROR_BASE + 14,
BAD_MIME_SNIFFER_RULE = APP_ERROR_BASE + 15,
NOT_A_MESSAGE = APP_ERROR_BASE + 16,
SHUTDOWN_CANCELLED = APP_ERROR_BASE + 17,
SHUTTING_DOWN = APP_ERROR_BASE + 18,
// Storage Kit/File System Errors
FILE_ERROR = STORAGE_ERROR_BASE + 0,
// 1 was B_FILE_NOT_FOUND (deprecated)
FILE_EXISTS = STORAGE_ERROR_BASE + 2,
ENTRY_NOT_FOUND = STORAGE_ERROR_BASE + 3,
NAME_TOO_LONG = STORAGE_ERROR_BASE + 4,
NOT_A_DIRECTORY = STORAGE_ERROR_BASE + 5,
DIRECTORY_NOT_EMPTY = STORAGE_ERROR_BASE + 6,
DEVICE_FULL = STORAGE_ERROR_BASE + 7,
READ_ONLY_DEVICE = STORAGE_ERROR_BASE + 8,
IS_A_DIRECTORY = STORAGE_ERROR_BASE + 9,
NO_MORE_FDS = STORAGE_ERROR_BASE + 10,
CROSS_DEVICE_LINK = STORAGE_ERROR_BASE + 11,
LINK_LIMIT = STORAGE_ERROR_BASE + 12,
BUSTED_PIPE = STORAGE_ERROR_BASE + 13,
UNSUPPORTED = STORAGE_ERROR_BASE + 14,
PARTITION_TOO_SMALL = STORAGE_ERROR_BASE + 15,
PARTIAL_READ = STORAGE_ERROR_BASE + 16,
PARTIAL_WRITE = STORAGE_ERROR_BASE + 17,
// Some POSIX errors
E2BIG = POSIX_ERROR_BASE + 1,
EFBIG = POSIX_ERROR_BASE + 4,
ENODEV = POSIX_ERROR_BASE + 7,
ERANGE = POSIX_ERROR_BASE + 17,
EOVERFLOW = POSIX_ERROR_BASE + 41,
EOPNOTSUPP = POSIX_ERROR_BASE + 43,
ENOSYS = POSIX_ERROR_BASE + 9,
EAGAIN = WOULD_BLOCK,
// New error codes that can be mapped to POSIX errors
TOO_MANY_ARGS_NEG = E2BIG,
FILE_TOO_LARGE_NEG = EFBIG,
DEVICE_NOT_FOUND_NEG = ENODEV,
RESULT_NOT_REPRESENTABLE_NEG = ERANGE,
BUFFER_OVERFLOW_NEG = EOVERFLOW,
NOT_SUPPORTED_NEG = EOPNOTSUPP,
TOO_MANY_ARGS_POS = -E2BIG,
FILE_TOO_LARGE_POS = -EFBIG,
DEVICE_NOT_FOUND_POS = -ENODEV,
RESULT_NOT_REPRESENTABLE_POS = -ERANGE,
BUFFER_OVERFLOW_POS = -EOVERFLOW,
NOT_SUPPORTED_POS = -EOPNOTSUPP,
// Media Kit Errors
STREAM_NOT_FOUND = MEDIA_ERROR_BASE + 0,
SERVER_NOT_FOUND = MEDIA_ERROR_BASE + 1,
RESOURCE_NOT_FOUND = MEDIA_ERROR_BASE + 2,
RESOURCE_UNAVAILABLE = MEDIA_ERROR_BASE + 3,
BAD_SUBSCRIBER = MEDIA_ERROR_BASE + 4,
SUBSCRIBER_NOT_ENTERED = MEDIA_ERROR_BASE + 5,
BUFFER_NOT_AVAILABLE = MEDIA_ERROR_BASE + 6,
LAST_BUFFER_ERROR = MEDIA_ERROR_BASE + 7,
MEDIA_SYSTEM_FAILURE = MEDIA_ERROR_BASE + 100,
MEDIA_BAD_NODE = MEDIA_ERROR_BASE + 101,
MEDIA_NODE_BUSY = MEDIA_ERROR_BASE + 102,
MEDIA_BAD_FORMAT = MEDIA_ERROR_BASE + 103,
MEDIA_BAD_BUFFER = MEDIA_ERROR_BASE + 104,
MEDIA_TOO_MANY_NODES = MEDIA_ERROR_BASE + 105,
MEDIA_TOO_MANY_BUFFERS = MEDIA_ERROR_BASE + 106,
MEDIA_NODE_ALREADY_EXISTS = MEDIA_ERROR_BASE + 107,
MEDIA_BUFFER_ALREADY_EXISTS = MEDIA_ERROR_BASE + 108,
MEDIA_CANNOT_SEEK = MEDIA_ERROR_BASE + 109,
MEDIA_CANNOT_CHANGE_RUN_MODE = MEDIA_ERROR_BASE + 110,
MEDIA_APP_ALREADY_REGISTERED = MEDIA_ERROR_BASE + 111,
MEDIA_APP_NOT_REGISTERED = MEDIA_ERROR_BASE + 112,
MEDIA_CANNOT_RECLAIM_BUFFERS = MEDIA_ERROR_BASE + 113,
MEDIA_BUFFERS_NOT_RECLAIMED = MEDIA_ERROR_BASE + 114,
MEDIA_TIME_SOURCE_STOPPED = MEDIA_ERROR_BASE + 115,
MEDIA_TIME_SOURCE_BUSY = MEDIA_ERROR_BASE + 116,
MEDIA_BAD_SOURCE = MEDIA_ERROR_BASE + 117,
MEDIA_BAD_DESTINATION = MEDIA_ERROR_BASE + 118,
MEDIA_ALREADY_CONNECTED = MEDIA_ERROR_BASE + 119,
MEDIA_NOT_CONNECTED = MEDIA_ERROR_BASE + 120,
MEDIA_BAD_CLIP_FORMAT = MEDIA_ERROR_BASE + 121,
MEDIA_ADDON_FAILED = MEDIA_ERROR_BASE + 122,
MEDIA_ADDON_DISABLED = MEDIA_ERROR_BASE + 123,
MEDIA_CHANGE_IN_PROGRESS = MEDIA_ERROR_BASE + 124,
MEDIA_STALE_CHANGE_COUNT = MEDIA_ERROR_BASE + 125,
MEDIA_ADDON_RESTRICTED = MEDIA_ERROR_BASE + 126,
MEDIA_NO_HANDLER = MEDIA_ERROR_BASE + 127,
MEDIA_DUPLICATE_FORMAT = MEDIA_ERROR_BASE + 128,
MEDIA_REALTIME_DISABLED = MEDIA_ERROR_BASE + 129,
MEDIA_REALTIME_UNAVAILABLE = MEDIA_ERROR_BASE + 130,
// Mail Kit Errors
MAIL_NO_DAEMON = MAIL_ERROR_BASE + 0,
MAIL_UNKNOWN_USER = MAIL_ERROR_BASE + 1,
MAIL_WRONG_PASSWORD = MAIL_ERROR_BASE + 2,
MAIL_UNKNOWN_HOST = MAIL_ERROR_BASE + 3,
MAIL_ACCESS_ERROR = MAIL_ERROR_BASE + 4,
MAIL_UNKNOWN_FIELD = MAIL_ERROR_BASE + 5,
MAIL_NO_RECIPIENT = MAIL_ERROR_BASE + 6,
MAIL_INVALID_MAIL = MAIL_ERROR_BASE + 7,
// Printing Errors
NO_PRINT_SERVER = PRINT_ERROR_BASE + 0,
// Device Kit Errors
DEV_INVALID_IOCTL = DEVICE_ERROR_BASE + 0,
DEV_NO_MEMORY = DEVICE_ERROR_BASE + 1,
DEV_BAD_DRIVE_NUM = DEVICE_ERROR_BASE + 2,
DEV_NO_MEDIA = DEVICE_ERROR_BASE + 3,
DEV_UNREADABLE = DEVICE_ERROR_BASE + 4,
DEV_FORMAT_ERROR = DEVICE_ERROR_BASE + 5,
DEV_TIMEOUT = DEVICE_ERROR_BASE + 6,
DEV_RECALIBRATE_ERROR = DEVICE_ERROR_BASE + 7,
DEV_SEEK_ERROR = DEVICE_ERROR_BASE + 8,
DEV_ID_ERROR = DEVICE_ERROR_BASE + 9,
DEV_READ_ERROR = DEVICE_ERROR_BASE + 10,
DEV_WRITE_ERROR = DEVICE_ERROR_BASE + 11,
DEV_NOT_READY = DEVICE_ERROR_BASE + 12,
DEV_MEDIA_CHANGED = DEVICE_ERROR_BASE + 13,
DEV_MEDIA_CHANGE_REQUESTED = DEVICE_ERROR_BASE + 14,
DEV_RESOURCE_CONFLICT = DEVICE_ERROR_BASE + 15,
DEV_CONFIGURATION_ERROR = DEVICE_ERROR_BASE + 16,
DEV_DISABLED_BY_USER = DEVICE_ERROR_BASE + 17,
DEV_DOOR_OPEN = DEVICE_ERROR_BASE + 18,
DEV_INVALID_PIPE = DEVICE_ERROR_BASE + 19,
DEV_CRC_ERROR = DEVICE_ERROR_BASE + 20,
DEV_STALLED = DEVICE_ERROR_BASE + 21,
DEV_BAD_PID = DEVICE_ERROR_BASE + 22,
DEV_UNEXPECTED_PID = DEVICE_ERROR_BASE + 23,
DEV_DATA_OVERRUN = DEVICE_ERROR_BASE + 24,
DEV_DATA_UNDERRUN = DEVICE_ERROR_BASE + 25,
DEV_FIFO_OVERRUN = DEVICE_ERROR_BASE + 26,
DEV_FIFO_UNDERRUN = DEVICE_ERROR_BASE + 27,
DEV_PENDING = DEVICE_ERROR_BASE + 28,
DEV_MULTIPLE_ERRORS = DEVICE_ERROR_BASE + 29,
DEV_TOO_LATE = DEVICE_ERROR_BASE + 30,
// Translation Kit Errors
TRANSLATION_BASE_ERROR = TRANSLATION_ERROR_BASE + 0,
NO_TRANSLATOR = TRANSLATION_ERROR_BASE + 1,
ILLEGAL_DATA = TRANSLATION_ERROR_BASE + 2,
}
errno :: #force_inline proc "contextless" () -> Errno {
return Errno(_errnop()^)
}
foreign import libroot "system:c"
foreign libroot {
_to_positive_error :: proc(error: c.int) -> c.int ---
_to_negative_error :: proc(error: c.int) -> c.int ---
_errnop :: proc() -> ^c.int ---
}
+168
View File
@@ -0,0 +1,168 @@
//+build haiku
package sys_haiku
import "core:c"
directory_which :: enum c.int {
// Per volume directories
DESKTOP_DIRECTORY = 0,
TRASH_DIRECTORY,
// System directories
SYSTEM_DIRECTORY = 1000,
SYSTEM_ADDONS_DIRECTORY = 1002,
SYSTEM_BOOT_DIRECTORY,
SYSTEM_FONTS_DIRECTORY,
SYSTEM_LIB_DIRECTORY,
SYSTEM_SERVERS_DIRECTORY,
SYSTEM_APPS_DIRECTORY,
SYSTEM_BIN_DIRECTORY,
SYSTEM_DOCUMENTATION_DIRECTORY = 1010,
SYSTEM_PREFERENCES_DIRECTORY,
SYSTEM_TRANSLATORS_DIRECTORY,
SYSTEM_MEDIA_NODES_DIRECTORY,
SYSTEM_SOUNDS_DIRECTORY,
SYSTEM_DATA_DIRECTORY,
SYSTEM_DEVELOP_DIRECTORY,
SYSTEM_PACKAGES_DIRECTORY,
SYSTEM_HEADERS_DIRECTORY,
SYSTEM_ETC_DIRECTORY = 2008,
SYSTEM_SETTINGS_DIRECTORY = 2010,
SYSTEM_LOG_DIRECTORY = 2012,
SYSTEM_SPOOL_DIRECTORY,
SYSTEM_TEMP_DIRECTORY,
SYSTEM_VAR_DIRECTORY,
SYSTEM_CACHE_DIRECTORY = 2020,
SYSTEM_NONPACKAGED_DIRECTORY = 2023,
SYSTEM_NONPACKAGED_ADDONS_DIRECTORY,
SYSTEM_NONPACKAGED_TRANSLATORS_DIRECTORY,
SYSTEM_NONPACKAGED_MEDIA_NODES_DIRECTORY,
SYSTEM_NONPACKAGED_BIN_DIRECTORY,
SYSTEM_NONPACKAGED_DATA_DIRECTORY,
SYSTEM_NONPACKAGED_FONTS_DIRECTORY,
SYSTEM_NONPACKAGED_SOUNDS_DIRECTORY,
SYSTEM_NONPACKAGED_DOCUMENTATION_DIRECTORY,
SYSTEM_NONPACKAGED_LIB_DIRECTORY,
SYSTEM_NONPACKAGED_HEADERS_DIRECTORY,
SYSTEM_NONPACKAGED_DEVELOP_DIRECTORY,
// User directories. These are interpreted in the context of the user making the find_directory call.
USER_DIRECTORY = 3000,
USER_CONFIG_DIRECTORY,
USER_ADDONS_DIRECTORY,
USER_BOOT_DIRECTORY,
USER_FONTS_DIRECTORY,
USER_LIB_DIRECTORY,
USER_SETTINGS_DIRECTORY,
USER_DESKBAR_DIRECTORY,
USER_PRINTERS_DIRECTORY,
USER_TRANSLATORS_DIRECTORY,
USER_MEDIA_NODES_DIRECTORY,
USER_SOUNDS_DIRECTORY,
USER_DATA_DIRECTORY,
USER_CACHE_DIRECTORY,
USER_PACKAGES_DIRECTORY,
USER_HEADERS_DIRECTORY,
USER_NONPACKAGED_DIRECTORY,
USER_NONPACKAGED_ADDONS_DIRECTORY,
USER_NONPACKAGED_TRANSLATORS_DIRECTORY,
USER_NONPACKAGED_MEDIA_NODES_DIRECTORY,
USER_NONPACKAGED_BIN_DIRECTORY,
USER_NONPACKAGED_DATA_DIRECTORY,
USER_NONPACKAGED_FONTS_DIRECTORY,
USER_NONPACKAGED_SOUNDS_DIRECTORY,
USER_NONPACKAGED_DOCUMENTATION_DIRECTORY,
USER_NONPACKAGED_LIB_DIRECTORY,
USER_NONPACKAGED_HEADERS_DIRECTORY,
USER_NONPACKAGED_DEVELOP_DIRECTORY,
USER_DEVELOP_DIRECTORY,
USER_DOCUMENTATION_DIRECTORY,
USER_SERVERS_DIRECTORY,
USER_APPS_DIRECTORY,
USER_BIN_DIRECTORY,
USER_PREFERENCES_DIRECTORY,
USER_ETC_DIRECTORY,
USER_LOG_DIRECTORY,
USER_SPOOL_DIRECTORY,
USER_VAR_DIRECTORY,
// Global directories
APPS_DIRECTORY = 4000,
PREFERENCES_DIRECTORY,
UTILITIES_DIRECTORY,
PACKAGE_LINKS_DIRECTORY,
// Obsolete: Legacy BeOS definition to be phased out
BEOS_DIRECTORY = 1000,
BEOS_SYSTEM_DIRECTORY,
BEOS_ADDONS_DIRECTORY,
BEOS_BOOT_DIRECTORY,
BEOS_FONTS_DIRECTORY,
BEOS_LIB_DIRECTORY,
BEOS_SERVERS_DIRECTORY,
BEOS_APPS_DIRECTORY,
BEOS_BIN_DIRECTORY,
BEOS_ETC_DIRECTORY,
BEOS_DOCUMENTATION_DIRECTORY,
BEOS_PREFERENCES_DIRECTORY,
BEOS_TRANSLATORS_DIRECTORY,
BEOS_MEDIA_NODES_DIRECTORY,
BEOS_SOUNDS_DIRECTORY,
}
find_path_flags :: enum c.int {
CREATE_DIRECTORY = 0x0001,
CREATE_PARENT_DIRECTORY = 0x0002,
EXISTING_ONLY = 0x0004,
// find_paths() only!
SYSTEM_ONLY = 0x0010,
USER_ONLY = 0x0020,
}
path_base_directory :: enum c.int {
INSTALLATION_LOCATION_DIRECTORY,
ADD_ONS_DIRECTORY,
APPS_DIRECTORY,
BIN_DIRECTORY,
BOOT_DIRECTORY,
CACHE_DIRECTORY,
DATA_DIRECTORY,
DEVELOP_DIRECTORY,
DEVELOP_LIB_DIRECTORY,
DOCUMENTATION_DIRECTORY,
ETC_DIRECTORY,
FONTS_DIRECTORY,
HEADERS_DIRECTORY,
LIB_DIRECTORY,
LOG_DIRECTORY,
MEDIA_NODES_DIRECTORY,
PACKAGES_DIRECTORY,
PREFERENCES_DIRECTORY,
SERVERS_DIRECTORY,
SETTINGS_DIRECTORY,
SOUNDS_DIRECTORY,
SPOOL_DIRECTORY,
TRANSLATORS_DIRECTORY,
VAR_DIRECTORY,
// find_path() only!
IMAGE_PATH = 1000,
PACKAGE_PATH,
}
// value that can be used instead of a pointer to a symbol in the program image
APP_IMAGE_SYMBOL :: rawptr(addr_t(0))
// pointer to a symbol in the callers image (same as B_CURRENT_IMAGE_SYMBOL)
current_image_symbol :: proc() -> rawptr { return rawptr(current_image_symbol) }
foreign import libroot "system:c"
foreign libroot {
find_directory :: proc(which: directory_which, volume: dev_t, createIt: bool, pathString: [^]c.char, length: i32) -> status_t ---
find_path :: proc(codePointer: rawptr, baseDirectory: path_base_directory, subPath: cstring, pathBuffer: [^]c.char, bufferSize: c.size_t) -> status_t ---
find_path_etc :: proc(codePointer: rawptr, dependency: cstring, architecture: cstring, baseDirectory: path_base_directory, subPath: cstring, flags: find_path_flags, pathBuffer: [^]c.char, bufferSize: c.size_t) -> status_t ---
find_path_for_path :: proc(path: cstring, baseDirectory: path_base_directory, subPath: cstring, pathBuffer: [^]c.char, bufferSize: c.size_t) -> status_t ---
find_path_for_path_etc :: proc(path: cstring, dependency: cstring, architecture: cstring, baseDirectory: path_base_directory, subPath: cstring, flags: find_path_flags, pathBuffer: [^]c.char, bufferSize: c.size_t) -> status_t ---
find_paths :: proc(baseDirectory: path_base_directory, subPath: cstring, _paths: ^[^][^]c.char, _pathCount: ^c.size_t) -> status_t ---
find_paths_etc :: proc(architecture: cstring, baseDirectory: path_base_directory, subPath: cstring, flags: find_path_flags, _paths: ^[^][^]c.char, _pathCount: ^c.size_t) -> status_t ---
}
+502
View File
@@ -0,0 +1,502 @@
//+build haiku
package sys_haiku
import "core:c"
import "core:sys/unix"
foreign import libroot "system:c"
PATH_MAX :: 1024
NAME_MAX :: 256
MAXPATHLEN :: PATH_MAX
FILE_NAME_LENGTH :: NAME_MAX
PATH_NAME_LENGTH :: MAXPATHLEN
OS_NAME_LENGTH :: 32
// Areas
area_info :: struct {
area: area_id,
name: [OS_NAME_LENGTH]c.char,
size: c.size_t,
lock: u32,
protection: u32,
team: team_id,
ram_size: u32,
copy_count: u32,
in_count: u32,
out_count: u32,
address: rawptr,
}
area_locking :: enum u32 {
NO_LOCK = 0,
LAZY_LOCK = 1,
FULL_LOCK = 2,
CONTIGUOUS = 3,
LOMEM = 4, // CONTIGUOUS, < 16 MB physical address
_32_BIT_FULL_LOCK = 5, // FULL_LOCK, < 4 GB physical addresses
_32_BIT_CONTIGUOUS = 6, // CONTIGUOUS, < 4 GB physical address
}
// for create_area() and clone_area()
address_spec :: enum u32 {
ANY_ADDRESS = 0,
EXACT_ADDRESS = 1,
BASE_ADDRESS = 2,
CLONE_ADDRESS = 3,
ANY_KERNEL_ADDRESS = 4,
// ANY_KERNEL_BLOCK_ADDRESS = 5,
RANDOMIZED_ANY_ADDRESS = 6,
RANDOMIZED_BASE_ADDRESS = 7,
}
area_protection_flags :: enum u32 {
READ_AREA = 1 << 0,
WRITE_AREA = 1 << 1,
EXECUTE_AREA = 1 << 2,
// "stack" protection is not available on most platforms - it's used
// to only commit memory as needed, and have guard pages at the
// bottom of the stack.
STACK_AREA = 1 << 3,
CLONEABLE_AREA = 1 << 8,
}
foreign libroot {
create_area :: proc(name: cstring, startAddress: ^rawptr, addressSpec: address_spec, size: c.size_t, lock: area_locking, protection: area_protection_flags) -> area_id ---
clone_area :: proc(name: cstring, destAddress: ^rawptr, addressSpec: address_spec, protection: area_protection_flags, source: area_id) -> area_id ---
find_area :: proc(name: cstring) -> area_id ---
area_for :: proc(address: rawptr) -> area_id ---
delete_area :: proc(id: area_id) -> status_t ---
resize_area :: proc(id: area_id, newSize: c.size_t) -> status_t ---
set_area_protection :: proc(id: area_id, newProtection: area_protection_flags) -> status_t ---
_get_area_info :: proc(id: area_id, areaInfo: ^area_info, size: c.size_t) -> status_t ---
_get_next_area_info :: proc(team: team_id, cookie: ^c.ssize_t, areaInfo: ^area_info, size: c.size_t) -> status_t ---
}
// Ports
port_info :: struct {
port: port_id,
team: team_id,
name: [OS_NAME_LENGTH]c.char,
capacity: i32, // queue depth
queue_count: i32, // # msgs waiting to be read
total_count: i32, // total # msgs read so far
}
port_flags :: enum u32 {
USE_USER_MEMCPY = 0x80000000,
// read the message, but don't remove it; kernel-only; memory must be locked
PEEK_PORT_MESSAGE = 0x100,
}
foreign libroot {
create_port :: proc(capacity: i32, name: cstring) -> port_id ---
find_port :: proc(name: cstring) -> port_id ---
read_port :: proc(port: port_id, code: ^i32, buffer: rawptr, bufferSize: c.size_t) -> c.ssize_t ---
read_port_etc :: proc(port: port_id, code: ^i32, buffer: rawptr, bufferSize: c.size_t, flags: port_flags, timeout: bigtime_t) -> c.ssize_t ---
write_port :: proc(port: port_id, code: i32, buffer: rawptr, bufferSize: c.size_t) -> status_t ---
write_port_etc :: proc(port: port_id, code: i32, buffer: rawptr, bufferSize: c.size_t, flags: port_flags, timeout: bigtime_t) -> status_t ---
close_port :: proc(port: port_id) -> status_t ---
delete_port :: proc(port: port_id) -> status_t ---
port_buffer_size :: proc(port: port_id) -> c.ssize_t ---
port_buffer_size_etc :: proc(port: port_id, flags: port_flags, timeout: bigtime_t) -> c.ssize_t ---
port_count :: proc(port: port_id) -> c.ssize_t ---
set_port_owner :: proc(port: port_id, team: team_id) -> status_t ---
_get_port_info :: proc(port: port_id, portInfo: ^port_info, portInfoSize: c.size_t) -> status_t ---
_get_next_port_info :: proc(team: team_id, cookie: ^i32, portInfo: ^port_info, portInfoSize: c.size_t) -> status_t ---
}
// Semaphores
sem_info :: struct {
sem: sem_id,
team: team_id,
name: [OS_NAME_LENGTH]c.char,
count: i32,
latest_holder: thread_id,
}
semaphore_flags :: enum u32 {
CAN_INTERRUPT = 0x01, // acquisition of the semaphore can be interrupted (system use only)
CHECK_PERMISSION = 0x04, // ownership will be checked (system use only)
KILL_CAN_INTERRUPT = 0x20, // acquisition of the semaphore can be interrupted by SIGKILL[THR], even if not CAN_INTERRUPT (system use only)
// release_sem_etc() only flags
DO_NOT_RESCHEDULE = 0x02, // thread is not rescheduled
RELEASE_ALL = 0x08, // all waiting threads will be woken up, count will be zeroed
RELEASE_IF_WAITING_ONLY = 0x10, // release count only if there are any threads waiting
}
foreign libroot {
create_sem :: proc(count: i32, name: cstring) -> sem_id ---
delete_sem :: proc(id: sem_id) -> status_t ---
acquire_sem :: proc(id: sem_id) -> status_t ---
acquire_sem_etc :: proc(id: sem_id, count: i32, flags: semaphore_flags, timeout: bigtime_t) -> status_t ---
release_sem :: proc(id: sem_id) -> status_t ---
release_sem_etc :: proc(id: sem_id, count: i32, flags: semaphore_flags) -> status_t ---
switch_sem :: proc(semToBeReleased: sem_id) -> status_t ---
switch_sem_etc :: proc(semToBeReleased: sem_id, id: sem_id, count: i32, flags: semaphore_flags, timeout: bigtime_t) -> status_t ---
get_sem_count :: proc(id: sem_id, threadCount: ^i32) -> status_t ---
set_sem_owner :: proc(id: sem_id, team: team_id) -> status_t ---
_get_sem_info :: proc(id: sem_id, info: ^sem_info, infoSize: c.size_t) -> status_t ---
_get_next_sem_info :: proc(team: team_id, cookie: ^i32, info: ^sem_info, infoSize: c.size_t) -> status_t ---
}
// Teams
team_info :: struct {
team: team_id,
thread_count: i32,
image_count: i32,
area_count: i32,
debugger_nub_thread: thread_id,
debugger_nub_port: port_id,
argc: i32,
args: [64]c.char,
uid: uid_t,
gid: gid_t,
// Haiku R1 extensions
real_uid: uid_t,
real_gid: gid_t,
group_id: pid_t,
session_id: pid_t,
parent: team_id,
name: [OS_NAME_LENGTH]c.char,
start_time: bigtime_t,
}
CURRENT_TEAM :: 0
SYSTEM_TEAM :: 1
team_usage_info :: struct {
user_time: bigtime_t,
kernel_time: bigtime_t,
}
team_usage_who :: enum i32 {
// compatible to sys/resource.h RUSAGE_SELF and RUSAGE_CHILDREN
SELF = 0,
CHILDREN = -1,
}
foreign libroot {
// see also: send_signal()
kill_team :: proc(team: team_id) -> status_t ---
_get_team_info :: proc(id: team_id, info: ^team_info, size: c.size_t) -> status_t ---
_get_next_team_info :: proc(cookie: ^i32, info: ^team_info, size: c.size_t) -> status_t ---
_get_team_usage_info :: proc(id: team_id, who: team_usage_who, info: ^team_usage_info, size: c.size_t) -> status_t ---
}
// Threads
thread_state :: enum c.int {
RUNNING = 1,
READY,
RECEIVING,
ASLEEP,
SUSPENDED,
WAITING,
}
thread_info :: struct {
thread: thread_id,
team: team_id,
name: [OS_NAME_LENGTH]c.char,
state: thread_state,
priority: thread_priority,
sem: sem_id,
user_time: bigtime_t,
kernel_time: bigtime_t,
stack_base: rawptr,
stack_end: rawptr,
}
thread_priority :: enum i32 {
IDLE_PRIORITY = 0,
LOWEST_ACTIVE_PRIORITY = 1,
LOW_PRIORITY = 5,
NORMAL_PRIORITY = 10,
DISPLAY_PRIORITY = 15,
URGENT_DISPLAY_PRIORITY = 20,
REAL_TIME_DISPLAY_PRIORITY = 100,
URGENT_PRIORITY = 110,
REAL_TIME_PRIORITY = 120,
}
FIRST_REAL_TIME_PRIORITY :: thread_priority.REAL_TIME_PRIORITY
// time base for snooze_*(), compatible with the clockid_t constants defined in <time.h>
SYSTEM_TIMEBASE :: 0
thread_func :: #type proc "c" (rawptr) -> status_t
foreign libroot {
spawn_thread :: proc(thread_func, name: cstring, priority: thread_priority, data: rawptr) -> thread_id ---
kill_thread :: proc(thread: thread_id) -> status_t ---
resume_thread :: proc(thread: thread_id) -> status_t ---
suspend_thread :: proc(thread: thread_id) -> status_t ---
rename_thread :: proc(thread: thread_id, newName: cstring) -> status_t ---
set_thread_priority :: proc(thread: thread_id, newPriority: thread_priority) -> status_t ---
exit_thread :: proc(status: status_t) ---
wait_for_thread :: proc(thread: thread_id, returnValue: ^status_t) -> status_t ---
// FIXME: Find and define those flags.
wait_for_thread_etc :: proc(id: thread_id, flags: u32, timeout: bigtime_t, _returnCode: ^status_t) -> status_t ---
on_exit_thread :: proc(callback: proc "c" (rawptr), data: rawptr) -> status_t ---
find_thread :: proc(name: cstring) -> thread_id ---
send_data :: proc(thread: thread_id, code: i32, buffer: rawptr, bufferSize: c.size_t) -> status_t ---
receive_data :: proc(sender: ^thread_id, buffer: rawptr, bufferSize: c.size_t) -> i32 ---
has_data :: proc(thread: thread_id) -> bool ---
snooze :: proc(amount: bigtime_t) -> status_t ---
// FIXME: Find and define those flags.
snooze_etc :: proc(amount: bigtime_t, timeBase: c.int, flags: u32) -> status_t ---
snooze_until :: proc(time: bigtime_t, timeBase: c.int) -> status_t ---
_get_thread_info :: proc(id: thread_id, info: ^thread_info, size: c.size_t) -> status_t ---
_get_next_thread_info :: proc(team: team_id, cookie: ^i32, info: ^thread_info, size: c.size_t) -> status_t ---
// bridge to the pthread API
get_pthread_thread_id :: proc(thread: pthread_t) -> thread_id ---
}
// Time
foreign libroot {
real_time_clock :: proc() -> c.ulong ---
set_real_time_clock :: proc(secsSinceJan1st1970: c.ulong) ---
real_time_clock_usecs :: proc() -> bigtime_t ---
// time since booting in microseconds
system_time :: proc() -> bigtime_t ---
// time since booting in nanoseconds
system_time_nsecs :: proc() -> nanotime_t ---
}
// Alarm
alarm_mode :: enum u32 {
ONE_SHOT_ABSOLUTE_ALARM = 1,
ONE_SHOT_RELATIVE_ALARM,
PERIODIC_ALARM, // "when" specifies the period
}
foreign libroot {
set_alarm :: proc(_when: bigtime_t, mode: alarm_mode) -> bigtime_t ---
}
// Debugger
foreign libroot {
debugger :: proc(message: cstring) ---
/*
calling this function with a non-zero value will cause your thread
to receive signals for any exceptional conditions that occur (i.e.
you'll get SIGSEGV for data access exceptions, SIGFPE for floating
point errors, SIGILL for illegal instructions, etc).
to re-enable the default debugger pass a zero.
*/
disable_debugger :: proc(state: c.int) -> c.int ---
}
// System information
cpu_info :: struct {
active_time: bigtime_t,
enabled: bool,
current_frequency: u64,
}
system_info :: struct {
boot_time: bigtime_t, // time of boot (usecs since 1/1/1970)
cpu_count: u32, // number of cpus
max_pages: u64, // total # of accessible pages
used_pages: u64, // # of accessible pages in use
cached_pages: u64,
block_cache_pages: u64,
ignored_pages: u64, // # of ignored/inaccessible pages
needed_memory: u64,
free_memory: u64,
max_swap_pages: u64,
free_swap_pages: u64,
page_faults: u32, // # of page faults
max_sems: u32,
used_sems: u32,
max_ports: u32,
used_ports: u32,
max_threads: u32,
used_threads: u32,
max_teams: u32,
used_teams: u32,
kernel_name: [FILE_NAME_LENGTH]c.char,
kernel_build_date: [OS_NAME_LENGTH]c.char,
kernel_build_time: [OS_NAME_LENGTH]c.char,
kernel_version: i64,
abi: u32, // the system API
}
topology_level_type :: enum c.int {
UNKNOWN,
ROOT,
SMT,
CORE,
PACKAGE,
}
cpu_platform :: enum c.int {
UNKNOWN,
x86,
x86_64,
PPC,
PPC_64,
M68K,
ARM,
ARM_64,
ALPHA,
MIPS,
SH,
SPARC,
RISC_V,
}
cpu_vendor :: enum c.int {
UNKNOWN,
AMD,
CYRIX,
IDT,
INTEL,
NATIONAL_SEMICONDUCTOR,
RISE,
TRANSMETA,
VIA,
IBM,
MOTOROLA,
NEC,
HYGON,
SUN,
FUJITSU,
}
cpu_topology_node_info :: struct {
id: u32,
type: topology_level_type,
level: u32,
data: struct #raw_union {
_root: struct {
platform: cpu_platform,
},
_package: struct {
vendor: cpu_vendor,
cache_line_size: u32
},
_core: struct {
model: u32,
default_frequency: u64,
},
},
}
// FIXME: Add cpuid_info when bit fields are ready.
foreign libroot {
get_system_info :: proc(info: ^system_info) -> status_t ---
_get_cpu_info_etc :: proc(firstCPU: u32, cpuCount: u32, info: ^cpu_info, size: c.size_t) -> status_t ---
get_cpu_topology_info :: proc(topologyInfos: [^]cpu_topology_node_info, topologyInfoCount: ^u32) -> status_t ---
is_computer_on :: proc() -> i32 ---
is_computer_on_fire :: proc() -> f64 ---
}
// Signal.h
SIG_BLOCK :: 1
SIG_UNBLOCK :: 2
SIG_SETMASK :: 3
/*
* The list of all defined signals:
*
* The numbering of signals for Haiku attempts to maintain
* some consistency with UN*X conventions so that things
* like "kill -9" do what you expect.
*/
SIGHUP :: 1 // hangup -- tty is gone!
SIGINT :: 2 // interrupt
SIGQUIT :: 3 // `quit' special character typed in tty
SIGILL :: 4 // illegal instruction
SIGCHLD :: 5 // child process exited
SIGABRT :: 6 // abort() called, dont' catch
SIGPIPE :: 7 // write to a pipe w/no readers
SIGFPE :: 8 // floating point exception
SIGKILL :: 9 // kill a team (not catchable)
SIGSTOP :: 10 // suspend a thread (not catchable)
SIGSEGV :: 11 // segmentation violation (read: invalid pointer)
SIGCONT :: 12 // continue execution if suspended
SIGTSTP :: 13 // `stop' special character typed in tty
SIGALRM :: 14 // an alarm has gone off (see alarm())
SIGTERM :: 15 // termination requested
SIGTTIN :: 16 // read of tty from bg process
SIGTTOU :: 17 // write to tty from bg process
SIGUSR1 :: 18 // app defined signal 1
SIGUSR2 :: 19 // app defined signal 2
SIGWINCH :: 20 // tty window size changed
SIGKILLTHR :: 21 // be specific: kill just the thread, not team
SIGTRAP :: 22 // Trace/breakpoint trap
SIGPOLL :: 23 // Pollable event
SIGPROF :: 24 // Profiling timer expired
SIGSYS :: 25 // Bad system call
SIGURG :: 26 // High bandwidth data is available at socket
SIGVTALRM :: 27 // Virtual timer expired
SIGXCPU :: 28 // CPU time limit exceeded
SIGXFSZ :: 29 // File size limit exceeded
SIGBUS :: 30 // access to undefined portion of a memory object
sigval :: struct #raw_union {
sival_int: c.int,
sival_ptr: rawptr,
}
siginfo_t :: struct {
si_signo: c.int, // signal number
si_code: c.int, // signal code
si_errno: c.int, // if non zero, an error number associated with this signal
si_pid: pid_t, // sending process ID
si_uid: uid_t, // real user ID of sending process
si_addr: rawptr, // address of faulting instruction
si_status: c.int, // exit value or signal
si_band: c.long, // band event for SIGPOLL
si_value: sigval, // signal value
}
foreign libroot {
// signal set (sigset_t) manipulation
sigemptyset :: proc(set: ^sigset_t) -> c.int ---
sigfillset :: proc(set: ^sigset_t) -> c.int ---
sigaddset :: proc(set: ^sigset_t, _signal: c.int) -> c.int ---
sigdelset :: proc(set: ^sigset_t, _signal: c.int) -> c.int ---
sigismember :: proc(set: ^sigset_t, _signal: c.int) -> c.int ---
// querying and waiting for signals
sigpending :: proc(set: ^sigset_t) -> c.int ---
sigsuspend :: proc(mask: ^sigset_t) -> c.int ---
sigpause :: proc(_signal: c.int) -> c.int ---
sigwait :: proc(set: ^sigset_t, _signal: ^c.int) -> c.int ---
sigwaitinfo :: proc(set: ^sigset_t, info: ^siginfo_t) -> c.int ---
sigtimedwait :: proc(set: ^sigset_t, info: ^siginfo_t, timeout: ^unix.timespec) -> c.int ---
send_signal :: proc(threadID: thread_id, signal: c.uint) -> c.int ---
set_signal_stack :: proc(base: rawptr, size: c.size_t) ---
}
+54
View File
@@ -0,0 +1,54 @@
//+build haiku
package sys_haiku
import "core:c"
status_t :: i32
bigtime_t :: i64
nanotime_t :: i64
type_code :: u32
perform_code :: u32
phys_addr_t :: uintptr
phys_size_t :: phys_addr_t
generic_addr_t :: uintptr
generic_size_t :: generic_addr_t
area_id :: i32
port_id :: i32
sem_id :: i32
team_id :: i32
thread_id :: i32
blkcnt_t :: i64
blksize_t :: i32
fsblkcnt_t :: i64
fsfilcnt_t :: i64
off_t :: i64
ino_t :: i64
cnt_t :: i32
dev_t :: i32
pid_t :: i32
id_t :: i32
uid_t :: u32
gid_t :: u32
mode_t :: u32
umode_t :: u32
nlink_t :: i32
caddr_t :: ^c.char
addr_t :: phys_addr_t
key_t :: i32
clockid_t :: i32
time_t :: i64 when ODIN_ARCH == .amd64 || ODIN_ARCH == .arm64 else i32
sig_atomic_t :: c.int
sigset_t :: u64
image_id :: i32
pthread_t :: rawptr
+71
View File
@@ -0,0 +1,71 @@
package unix
import "core:c"
pthread_t :: distinct rawptr
pthread_attr_t :: distinct rawptr
pthread_mutex_t :: distinct rawptr
pthread_mutexattr_t :: distinct rawptr
pthread_cond_t :: distinct rawptr
pthread_condattr_t :: distinct rawptr
pthread_rwlock_t :: distinct rawptr
pthread_rwlockattr_t :: distinct rawptr
pthread_barrier_t :: distinct rawptr
pthread_barrierattr_t :: distinct rawptr
pthread_spinlock_t :: distinct rawptr
pthread_key_t :: distinct c.int
pthread_once_t :: struct {
state: c.int,
mutex: pthread_mutex_t,
}
PTHREAD_MUTEX_DEFAULT :: 0
PTHREAD_MUTEX_NORMAL :: 1
PTHREAD_MUTEX_ERRORCHECK :: 2
PTHREAD_MUTEX_RECURSIVE :: 3
PTHREAD_DETACHED :: 0x1
PTHREAD_SCOPE_SYSTEM :: 0x2
PTHREAD_INHERIT_SCHED :: 0x4
PTHREAD_NOFLOAT :: 0x8
PTHREAD_CREATE_DETACHED :: PTHREAD_DETACHED
PTHREAD_CREATE_JOINABLE :: 0
PTHREAD_SCOPE_PROCESS :: 0
PTHREAD_EXPLICIT_SCHED :: 0
SCHED_FIFO :: 1
SCHED_RR :: 2
SCHED_SPORADIC :: 3
SCHED_OTHER :: 4
sched_param :: struct {
sched_priority: c.int,
}
sem_t :: distinct rawptr
PTHREAD_CANCEL_ENABLE :: 0
PTHREAD_CANCEL_DISABLE :: 1
PTHREAD_CANCEL_DEFERRED :: 0
PTHREAD_CANCEL_ASYNCHRONOUS :: 2
foreign import libc "system:c"
@(default_calling_convention="c")
foreign libc {
sem_open :: proc(name: cstring, flags: c.int) -> ^sem_t ---
sem_init :: proc(sem: ^sem_t, pshared: c.int, initial_value: c.uint) -> c.int ---
sem_destroy :: proc(sem: ^sem_t) -> c.int ---
sem_post :: proc(sem: ^sem_t) -> c.int ---
sem_wait :: proc(sem: ^sem_t) -> c.int ---
sem_trywait :: proc(sem: ^sem_t) -> c.int ---
pthread_yield :: proc() ---
pthread_setcancelstate :: proc (state: c.int, old_state: ^c.int) -> c.int ---
pthread_setcanceltype :: proc (type: c.int, old_type: ^c.int) -> c.int ---
pthread_cancel :: proc (thread: pthread_t) -> c.int ---
}
+17 -9
View File
@@ -1,4 +1,4 @@
//+build linux, darwin, freebsd, openbsd
//+build linux, darwin, freebsd, openbsd, haiku
package unix
foreign import "system:pthread"
@@ -16,6 +16,8 @@ foreign pthread {
// retval is a pointer to a location to put the return value of the thread proc.
pthread_join :: proc(t: pthread_t, retval: ^rawptr) -> c.int ---
pthread_kill :: proc(t: pthread_t, sig: c.int) -> c.int ---
pthread_self :: proc() -> pthread_t ---
pthread_equal :: proc(a, b: pthread_t) -> b32 ---
@@ -31,15 +33,9 @@ foreign pthread {
pthread_attr_getschedparam :: proc(attrs: ^pthread_attr_t, param: ^sched_param) -> c.int ---
pthread_attr_setschedparam :: proc(attrs: ^pthread_attr_t, param: ^sched_param) -> c.int ---
pthread_attr_getschedpolicy :: proc(t: ^pthread_attr_t, policy: ^c.int) -> c.int ---
pthread_attr_setschedpolicy :: proc(t: ^pthread_attr_t, policy: c.int) -> c.int ---
// states: PTHREAD_CREATE_DETACHED, PTHREAD_CREATE_JOINABLE
pthread_attr_setdetachstate :: proc(attrs: ^pthread_attr_t, detach_state: c.int) -> c.int ---
// scheds: PTHREAD_INHERIT_SCHED, PTHREAD_EXPLICIT_SCHED
pthread_attr_setinheritsched :: proc(attrs: ^pthread_attr_t, sched: c.int) -> c.int ---
// NOTE(tetra, 2019-11-06): WARNING: Different systems have different alignment requirements.
// For maximum usefulness, use the OS's page size.
// ALSO VERY MAJOR WARNING: `stack_ptr` must be the LAST byte of the stack on systems
@@ -52,8 +48,20 @@ foreign pthread {
pthread_attr_setstack :: proc(attrs: ^pthread_attr_t, stack_ptr: rawptr, stack_size: u64) -> c.int ---
pthread_attr_getstack :: proc(attrs: ^pthread_attr_t, stack_ptr: ^rawptr, stack_size: ^u64) -> c.int ---
sched_yield :: proc() -> c.int ---
pthread_sigmask :: proc(how: c.int, set: rawptr, oldset: rawptr) -> c.int ---
sched_yield :: proc() -> c.int ---
}
// NOTE: Unimplemented in Haiku.
when ODIN_OS != .Haiku {
foreign pthread {
// scheds: PTHREAD_INHERIT_SCHED, PTHREAD_EXPLICIT_SCHED
pthread_attr_setinheritsched :: proc(attrs: ^pthread_attr_t, sched: c.int) -> c.int ---
pthread_attr_getschedpolicy :: proc(t: ^pthread_attr_t, policy: ^c.int) -> c.int ---
pthread_attr_setschedpolicy :: proc(t: ^pthread_attr_t, policy: c.int) -> c.int ---
}
}
@(default_calling_convention="c")
+1 -1
View File
@@ -1,4 +1,4 @@
//+build linux, darwin, freebsd, openbsd
//+build linux, darwin, freebsd, openbsd, haiku
package unix
when ODIN_OS == .Darwin {