initial support for haiku sync update

* add cpu count
* use haiku find_directory
* add definitions and exports for building in haiku
This commit is contained in:
Al Hoang 2021-01-17 13:29:00 -06:00 committed by Andrew Kelley
parent 6b0372229d
commit c17396691c
9 changed files with 137 additions and 34 deletions

View File

@ -504,6 +504,13 @@ pub fn cpuCount() CpuCountError!usize {
};
return @intCast(usize, count);
}
if (std.Target.current.os.tag == .haiku) {
var count: u32 = undefined;
var system_info: os.system_info = undefined;
const rc = os.system.get_system_info(&system_info);
count = system_info.cpu_count;
return @intCast(usize, count);
}
var count: c_int = undefined;
var count_len: usize = @sizeOf(c_int);
const name = if (comptime std.Target.current.isDarwin()) "hw.logicalcpu" else "hw.ncpu";
@ -538,6 +545,9 @@ pub fn getCurrentThreadId() u64 {
.openbsd => {
return @bitCast(u32, c.getthrid());
},
.haiku => {
return @bitCast(u32, c.find_thread(null));
},
else => {
@compileError("getCurrentThreadId not implemented for this platform");
},

View File

@ -14,9 +14,20 @@ extern "c" fn _errnop() *c_int;
pub const _errno = _errnop;
pub extern "c" fn find_directory(which: c_int, volume: i32, createIt: bool, path_ptr: [*]u8, length: i32) u64;
pub extern "c" fn find_thread(thread_name: ?*c_void) i32;
pub extern "c" fn get_system_info(system_info: *system_info) usize;
// TODO revisit if abi changes or better option becomes apparent
pub extern "c" fn _get_next_image_info(team: c_int, cookie: *i32, image_info: *image_info) usize;
pub extern "c" fn _kern_read_dir(fd: c_int, buf_ptr: [*]u8, nbytes: usize, maxcount: u32) usize;
pub extern "c" fn _get_next_image_info(team: c_int, cookie: *i32, image_info: *image_info) usize;
pub extern "c" fn _kern_read_stat(fd: c_int, path_ptr: [*]u8, traverse_link: bool, libc_stat: *libc_stat, stat_size: i32) usize;
pub extern "c" fn _kern_get_current_team() i32;
pub const sem_t = extern struct {
_magic: u32,
@ -27,6 +38,14 @@ pub const sem_t = extern struct {
_padding: u32,
};
pub const pthread_attr_t = extern struct {
__detach_state: i32,
__sched_priority: i32,
__stack_size: i32,
__guard_size: i32,
__stack_address: ?*c_void,
};
pub const pthread_mutex_t = extern struct {
flags: u32 = 0,
lock: i32 = 0,
@ -34,7 +53,6 @@ pub const pthread_mutex_t = extern struct {
owner: i32 = -1,
owner_count: i32 = 0,
};
pub const pthread_cond_t = extern struct {
flags: u32 = 0,
unused: i32 = -42,

View File

@ -29,6 +29,7 @@ const os_has_fork = switch (std.Target.current.os.tag) {
.solaris,
.tvos,
.watchos,
.haiku,
=> true,
else => false,

View File

@ -472,8 +472,25 @@ pub const Dir = struct {
continue :start_over;
}
// TODO: determine entry kind
const entry_kind = Entry.Kind.File;
var stat_info: os.libc_stat = undefined;
const rc2 = os.system._kern_read_stat(
self.dir.fd,
&haiku_entry.d_name,
false,
&stat_info,
0,
);
const statmode = stat_info.mode & os.S_IFMT;
const entry_kind = switch (statmode) {
os.S_IFDIR => Entry.Kind.Directory,
os.S_IFBLK => Entry.Kind.BlockDevice,
os.S_IFCHR => Entry.Kind.CharacterDevice,
os.S_IFLNK => Entry.Kind.SymLink,
os.S_IFREG => Entry.Kind.File,
os.S_IFIFO => Entry.Kind.NamedPipe,
else => Entry.Kind.Unknown,
};
return Entry{
.name = name,
@ -676,7 +693,13 @@ pub const Dir = struct {
pub fn iterate(self: Dir) Iterator {
switch (builtin.os.tag) {
.macos, .ios, .freebsd, .netbsd, .dragonfly, .openbsd, => return Iterator{
.macos,
.ios,
.freebsd,
.netbsd,
.dragonfly,
.openbsd,
=> return Iterator{
.dir = self,
.seek = 0,
.index = 0,

View File

@ -57,11 +57,16 @@ pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataD
return fs.path.join(allocator, &[_][]const u8{ home_dir, ".local", "share", appname });
},
.haiku => {
const home_dir = os.getenv("HOME") orelse {
// TODO look in /etc/passwd
return error.AppDataDirUnavailable;
};
return fs.path.join(allocator, &[_][]const u8{ home_dir, "config", "settings", appname });
var dir_path_ptr: [*:0]u8 = undefined;
// TODO look into directory_which
const be_user_settings = 0xbbe;
const rc = os.system.find_directory(be_user_settings, -1, true, dir_path_ptr, 1) ;
const settings_dir = try allocator.dupeZ(u8, mem.spanZ(dir_path_ptr));
defer allocator.free(settings_dir);
switch (rc) {
0 => return fs.path.join(allocator, &[_][]const u8{ settings_dir, appname }),
else => return error.AppDataDirUnavailable,
}
},
else => @compileError("Unsupported OS"),
}

View File

@ -3941,6 +3941,9 @@ pub fn sysctl(
if (builtin.os.tag == .wasi) {
@panic("unsupported");
}
if (builtin.os.tag == .haiku) {
@panic("unsupported");
}
const name_len = math.cast(c_uint, name.len) catch return error.NameTooLong;
switch (errno(system.sysctl(name.ptr, name_len, oldp, oldlenp, newp, newlen))) {
@ -3965,6 +3968,9 @@ pub fn sysctlbynameZ(
if (builtin.os.tag == .wasi) {
@panic("unsupported");
}
if (builtin.os.tag == .haiku) {
@panic("unsupported");
}
switch (errno(system.sysctlbyname(name, oldp, oldlenp, newp, newlen))) {
0 => return,

View File

@ -6,8 +6,6 @@
const std = @import("../../std.zig");
const maxInt = std.math.maxInt;
// See https://svnweb.freebsd.org/base/head/sys/sys/_types.h?view=co
// TODO: audit pid_t/mode_t. They should likely be i32 and u16, respectively
pub const fd_t = c_int;
pub const pid_t = c_int;
pub const uid_t = u32;
@ -30,6 +28,11 @@ pub const Kevent = extern struct {
// Modes and flags for dlopen()
// include/dlfcn.h
pub const POLLIN = 0x0001;
pub const POLLERR = 0x0004;
pub const POLLNVAL = 0x1000;
pub const POLLHUP = 0x0080;
/// Bind function calls lazily.
pub const RTLD_LAZY = 1;
@ -119,41 +122,43 @@ pub const msghdr_const = extern struct {
pub const off_t = i64;
pub const ino_t = u64;
pub const nfds_t = u32;
pub const pollfd = extern struct {
fd: i32,
events: i16,
revents: i16,
};
pub const libc_stat = extern struct {
dev: u64,
ino: ino_t,
nlink: usize,
mode: u16,
__pad0: u16,
uid: uid_t,
gid: gid_t,
__pad1: u32,
rdev: u64,
dev: i32,
ino: u64,
mode: u32,
nlink: i32,
uid: i32,
gid: i32,
size: i64,
rdev: i32,
blksize: i32,
atim: timespec,
mtim: timespec,
ctim: timespec,
birthtim: timespec,
size: off_t,
crtim: timespec,
st_type: u32,
blocks: i64,
blksize: isize,
flags: u32,
gen: u64,
__spare: [10]u64,
pub fn atime(self: @This()) timespec {
return self.atim;
}
pub fn mtime(self: @This()) timespec {
return self.mtim;
}
pub fn ctime(self: @This()) timespec {
return self.ctim;
}
pub fn crtime(self: @This()) timespec {
return self.crtim;
}
};
pub const timespec = extern struct {
@ -192,6 +197,34 @@ pub const image_info = extern struct {
abi: i32,
};
pub const system_info = extern struct {
boot_time: i64,
cpu_count: u32,
max_pages: u64,
used_pages: u64,
cached_pages: u64,
block_cache_pages: u64,
ignored_pages: u64,
needed_memory: u64,
free_memory: u64,
max_swap_pages: u64,
free_swap_pages: u64,
page_faults: u32,
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: [256]u8,
kernel_build_date: [32]u8,
kernel_build_time: [32]u8,
kernel_version: i64,
abi: u32,
};
pub const in_port_t = u16;
pub const sa_family_t = u8;
@ -1408,3 +1441,10 @@ pub const rlimit = extern struct {
pub const SHUT_RD = 0;
pub const SHUT_WR = 1;
pub const SHUT_RDWR = 2;
// TODO fill out if needed
pub const directory_which = extern enum(c_int) {
B_USER_SETTINGS_DIRECTORY = 0xbbe,
_,
};

View File

@ -1566,8 +1566,7 @@ pub const Target = struct {
.other,
=> return result,
// Operating systems in this list have been verified as not having a standard
// dynamic linker path.
// TODO revisit when multi-arch for Haiku is available
.haiku => return copy(&result, "/system/runtime_loader"),
// TODO go over each item in this list and either move it to the above list, or

View File

@ -196,6 +196,7 @@ pub const LibCInstallation = struct {
switch (Target.current.os.tag) {
.freebsd, .netbsd, .openbsd => self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/usr/lib"),
.linux, .dragonfly => batch.add(&async self.findNativeCrtDirPosix(args)),
.haiku => self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/system/develop/lib"),
else => {},
}
break :blk batch.wait();