Skip to content

Commit 08f7d9e

Browse files
committed
Implement Linux, FreeBSD
1 parent 876dbb8 commit 08f7d9e

File tree

6 files changed

+55
-5
lines changed

6 files changed

+55
-5
lines changed

.github/workflows/build.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ on:
2525
- .gitignore
2626

2727
jobs:
28-
check-other-targets:
28+
check:
2929
name: Type checking (${{ matrix.target.name }})
3030
runs-on: ubuntu-20.04
3131
if: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork) || github.event_name == 'push' }}
@@ -49,7 +49,7 @@ jobs:
4949
uses: actions-rs/toolchain@v1
5050
with:
5151
profile: minimal
52-
toolchain: 1.36
52+
toolchain: 1.28
5353
target: ${{ matrix.target.triple }}
5454
override: true
5555

@@ -58,7 +58,7 @@ jobs:
5858
with:
5959
key: ${{ matrix.target.triple }}
6060

61-
- name: Check feature powerset
61+
- name: Type checking
6262
uses: actions-rs/cargo@v1
6363
with:
6464
command: check

Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
name = "num_threads"
33
version = "0.1.0"
44
authors = ["Jacob Pratt <[email protected]>"]
5-
edition = "2018"
65
repository = "https://github.com/jhpratt/thread_count"
76
categories = ["api-bindings", "hardware-support", "os"]
87
license = "MIT OR Apache-2.0"
@@ -14,3 +13,6 @@ all-features = true
1413
targets = ["x86_64-unknown-linux-gnu"]
1514

1615
[dependencies]
16+
17+
[target.'cfg(target_os = "freebsd")'.dependencies]
18+
libc = "0.2.107"

src/freebsd.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
extern crate libc;
2+
3+
use std::num::NonZeroUsize;
4+
5+
extern "C" {
6+
fn kinfo_getproc(pid: libc::pid_t) -> *mut libc::kinfo_proc;
7+
}
8+
9+
pub(crate) fn num_threads() -> Option<NonZeroUsize> {
10+
// Safety: `kinfo_getproc` and `getpid` are both thread-safe. All invariants of `as_ref` are
11+
// upheld.
12+
NonZeroUsize::new(unsafe { kinfo_getproc(libc::getpid()).as_ref() }?.ki_numthreads as usize)
13+
}

src/imp.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
//! Fallback if no OS matches.
2+
3+
use std::num::NonZeroUsize;
4+
5+
pub(crate) fn num_threads() -> Option<NonZeroUsize> {
6+
None
7+
}

src/lib.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,19 @@
1-
//! Minimum supported Rust version: 1.36
1+
//! Minimum supported Rust version: 1.28
2+
3+
use std::num::NonZeroUsize;
4+
5+
#[cfg_attr(target_os = "linux", path = "linux.rs")]
6+
#[cfg_attr(target_os = "freebsd", path = "freebsd.rs")]
7+
mod imp;
8+
9+
/// Obtain the number of threads currently part of the active process. Returns `None` if the number
10+
/// of threads cannot be determined.
11+
pub fn num_threads() -> Option<NonZeroUsize> {
12+
imp::num_threads()
13+
}
14+
15+
/// Determine if the current process is single-threaded. Returns `None` if the number of threads
16+
/// cannot be determined.
17+
pub fn is_single_threaded() -> Option<bool> {
18+
num_threads().map(|n| n.get() == 1)
19+
}

src/linux.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
use std::fs;
2+
use std::num::NonZeroUsize;
3+
4+
pub(crate) fn num_threads() -> Option<NonZeroUsize> {
5+
fs::read_dir("/proc/self/task")
6+
// If we can't read the directory, return `None`.
7+
.ok()
8+
// The number of files in the directory is the number of threads.
9+
.and_then(|tasks| NonZeroUsize::new(tasks.count()))
10+
}

0 commit comments

Comments
 (0)