-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added semaphore support for Linux platform #83
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,34 @@ | ||
module par.config | ||
|
||
import std.compilerInfo | ||
import std.ptr | ||
|
||
datatype NativeThreadHandle = Byte Ptr // Opaque type | ||
[ct] if platformName == "Linux" | ||
datatype NativeThreadHandle = ULong | ||
else | ||
datatype NativeThreadHandle = Byte Ptr // Opaque type | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [minor, not introduced in this patch] |
||
|
||
fun >>(h: NativeThreadHandle, os: @OutStream) | ||
if ( h.impl.isSet ) | ||
os << mkStreamRefWrapper(h.impl.get) | ||
else | ||
os << "null" | ||
|
||
using InvalidThreadHandle = NativeThreadHandle() | ||
fun >>(h: NativeThreadHandle, os: @OutStream) | ||
if ( h.impl.isSet ) | ||
os << mkStreamRefWrapper(h.impl.get) | ||
else | ||
os << "null" | ||
|
||
using InvalidThreadHandle = NativeThreadHandle() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you don't define |
||
|
||
//! Get the number of available logical CPU cores for our process | ||
//! This dictates how much parallelism we have to be exploit | ||
fun getAvailableCoresNum(): UInt | ||
var maxProcs: Long = _Impl.sysconf(_Impl._SC_NPROCESSORS_ONLN) | ||
return ife(maxProcs<1, UInt(1), UInt(maxProcs)) | ||
|
||
return ife(maxProcs < 1, UInt(1), UInt(maxProcs)) | ||
// TODO: also consider process affinity | ||
|
||
package _Impl | ||
using _SC_NPROCESSORS_ONLN = 58 | ||
|
||
[native("sysconf")] fun sysconf(name: Int): Long | ||
[ct] if platformName == "Darwin" | ||
using _SC_NPROCESSORS_ONLN = 58 | ||
else | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would also test for Linux on the else branch. Just to be sure |
||
using _SC_NPROCESSORS_ONLN = 84 | ||
|
||
[native("sysconf")] fun sysconf(name: Int): Long |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,12 @@ | ||
module par.semaphore | ||
|
||
import std.compilerInfo | ||
import config | ||
|
||
datatype TimeSpecT | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should not be public to this file |
||
tv_sec: Int | ||
tv_nsec: Long | ||
|
||
//! Allows a limited numbers of threads to simultaneously "acquire" a resource | ||
//! before releasing it. | ||
//! Compared to the mutex, we can release the semaphore without acquiring it | ||
|
@@ -10,35 +15,59 @@ datatype Semaphore | |
|
||
fun ctor(this: @Semaphore, startValue: UInt = 0) | ||
_handle ctor | ||
var res = _Impl.semaphore_create(_Impl.mach_task_self(), _handle, _Impl.SYNC_POLICY_FIFO, Int(startValue)) | ||
[ct] if platformName == "Darwin" | ||
var res = _Impl.semaphore_create(_Impl.mach_task_self(), _handle, _Impl.SYNC_POLICY_FIFO, Int(startValue)) | ||
else | ||
var res = _Impl.sem_init(_handle, Int(0), UInt(startValue)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Didn't you implement this in a Posix header? |
||
|
||
fun dtor(this: @Semaphore) | ||
_Impl.semaphore_destroy(_Impl.mach_task_self(), _handle) | ||
[ct] if platformName == "Darwin" | ||
_Impl.semaphore_destroy(_Impl.mach_task_self(), _handle) | ||
else | ||
_Impl.sem_destroy(_handle) | ||
|
||
//! Increments the counter of the semaphore | ||
fun release(s: @Semaphore) | ||
_Impl.semaphore_signal(s._handle) | ||
[ct] if platformName == "Darwin" | ||
_Impl.semaphore_signal(s._handle) | ||
else | ||
_Impl.sem_post(s._handle) | ||
|
||
//! Decrements the semaphore counter | ||
//! If the counter reaches zero, the call blocks until somebody calls 'release' | ||
fun acquire(s: @Semaphore) | ||
while 0 != _Impl.semaphore_wait(s._handle) | ||
/*keep trying*/; | ||
[ct] if platformName == "Darwin" | ||
while 0 != _Impl.semaphore_wait(s._handle) | ||
/* keep trying */; | ||
else | ||
while 0 != _Impl.sem_wait(s._handle) | ||
/* keep trying */; | ||
|
||
package _Impl | ||
using TaskT = Int | ||
using SemaphoreT = Int | ||
using SYNC_POLICY_FIFO = 0 | ||
[ct] if platformName == "Darwin" | ||
using TaskT = Int | ||
using SYNC_POLICY_FIFO = 0 | ||
|
||
[native("mach_task_self")] fun mach_task_self(): TaskT; | ||
[native("semaphore_create")] fun semaphore_create(task: TaskT, s: @SemaphoreT, policy, value: Int): Int; | ||
[native("semaphore_destroy")] fun semaphore_destroy(task: TaskT, s: SemaphoreT): Int; | ||
[native("semaphore_signal")] fun semaphore_signal(s: SemaphoreT): Int; | ||
[native("semaphore_wait")] fun semaphore_wait(s: SemaphoreT): Int; | ||
using SemaphoreT = Int | ||
|
||
//using SemType = Int; | ||
[ct] if platformName == "Linux" | ||
using ModeT = Int | ||
|
||
//[native("sem_init")] fun sem_init(s: @SemType, pshared: Int, value: UInt): Int; | ||
//[native("sem_destroy")] fun sem_destroy(s: @SemType): Int; | ||
//[native("sem_wait")] fun sem_wait(s: @SemType): Int; | ||
//[native("sem_post")] fun sem_post(s: @SemType): Int; | ||
[ct] if platformName == "Darwin" | ||
[native("mach_task_self")] fun mach_task_self(): TaskT; | ||
[native("semaphore_create")] fun semaphore_create(task: TaskT, s: @SemaphoreT, policy, value: Int): Int; | ||
[native("semaphore_destroy")] fun semaphore_destroy(task: TaskT, s: SemaphoreT): Int; | ||
[native("semaphore_signal")] fun semaphore_signal(s: SemaphoreT): Int; | ||
[native("semaphore_wait")] fun semaphore_wait(s: SemaphoreT): Int; | ||
else | ||
[native("sem_init")] fun sem_init(sem: @SemaphoreT, pshared: Int, value: UInt): Int | ||
[native("sem_destroy")] fun sem_destroy(sem: @SemaphoreT): Int | ||
[native("sem_wait")] fun sem_wait(sem: @SemaphoreT): Int | ||
[native("sem_trywait")] fun sem_trywait(sem: @SemaphoreT): Int | ||
[native("sem_timedwait")] fun sem_timedwait(sem: @SemaphoreT, timeout: @TimeSpecT): Int | ||
[native("sem_post")] fun sem_post(sem: @SemaphoreT): Int | ||
[native("sem_getvalue")] fun sem_getvalue(sem: @SemaphoreT, sval: @Int): Int | ||
[native("sem_close")] fun sem_close(sem: @SemaphoreT): Int | ||
[native("sem_unlink")] fun sem_unlink(name: @Char): Int | ||
[native("sem_open")] fun sem_open(name: @Char, oflag: Int): @SemaphoreT | ||
[native("sem_open")] fun sem_open(name: @Char, oflag: Int, mode: ModeT, value: UInt): @SemaphoreT |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you also need to add the
>>
operator for the new type (if I remember correctly it will not be autogenerated, so you can't print a NativeThreadHandle)