sync: new_mutex() and new_waitgroup()

pull/2552/head
Delyan Angelov 2019-10-25 17:24:40 +03:00 committed by Alexander Medvednikov
parent e04c4ad852
commit 32b3611026
4 changed files with 41 additions and 9 deletions

View File

@ -17,7 +17,7 @@ struct Story {
struct Fetcher { struct Fetcher {
mut: mut:
mu sync.Mutex mu &sync.Mutex
ids []int ids []int
cursor int cursor int
wg &sync.WaitGroup wg &sync.WaitGroup
@ -65,12 +65,15 @@ fn main() {
ids = tmp ids = tmp
} }
mut wg := &sync.WaitGroup{} wg := sync.new_waitgroup()
fetcher := &Fetcher{ids: ids, wg: wg} // wg sent via ptr mtx := sync.new_mutex()
wg.add(ids.len) mut fetcher := &Fetcher{ids: ids}
fetcher.mu = &mtx
fetcher.wg = &wg
fetcher.wg.add(ids.len)
for i := 0; i < NR_THREADS; i++ { for i := 0; i < NR_THREADS; i++ {
go fetcher.fetch() go fetcher.fetch()
} }
wg.wait() fetcher.wg.wait()
} }

View File

@ -5,10 +5,18 @@
module sync module sync
#include <pthread.h> #include <pthread.h>
//[init_with=new_mutex] // TODO: implement support for this struct attribute, and disallow Mutex{} from outside the sync.new_mutex() function.
pub struct Mutex { pub struct Mutex {
mutex C.pthread_mutex_t mutex C.pthread_mutex_t
} }
pub fn new_mutex() Mutex {
m := Mutex{}
C.pthread_mutex_init( &m.mutex, C.NULL)
return m
}
pub fn (m mut Mutex) lock() { pub fn (m mut Mutex) lock() {
C.pthread_mutex_lock(&m.mutex) C.pthread_mutex_lock(&m.mutex)
} }

View File

@ -7,6 +7,7 @@ module sync
// Mutex HANDLE // Mutex HANDLE
type MHANDLE voidptr type MHANDLE voidptr
//[init_with=new_mutex] // TODO: implement support for this struct attribute, and disallow Mutex{} from outside the sync.new_mutex() function.
pub struct Mutex { pub struct Mutex {
mut: mut:
mx MHANDLE // mutex handle mx MHANDLE // mutex handle
@ -38,6 +39,19 @@ const (
WAIT_FAILED = 0xFFFFFFFF WAIT_FAILED = 0xFFFFFFFF
) )
pub fn new_mutex() Mutex {
sm := Mutex{}
unsafe {
mut m := sm
m.mx = C.CreateMutex(0, false, 0)
if isnil(m.mx) {
m.state = .broken // handle broken and mutex state are broken
return sm
}
return sm
}
}
pub fn (m mut Mutex) lock() { pub fn (m mut Mutex) lock() {
// if mutex handle not initalized // if mutex handle not initalized
if isnil(m.mx) { if isnil(m.mx) {
@ -49,9 +63,9 @@ pub fn (m mut Mutex) lock() {
} }
state := C.WaitForSingleObject(m.mx, INFINITE) // infinite wait state := C.WaitForSingleObject(m.mx, INFINITE) // infinite wait
m.state = match state { m.state = match state {
WAIT_ABANDONED => { MutexState.abandoned } WAIT_ABANDONED { MutexState.abandoned }
WAIT_OBJECT_0 => { MutexState.waiting } WAIT_OBJECT_0 { MutexState.waiting }
else => { MutexState.broken } else { MutexState.broken }
} }
} }

View File

@ -4,12 +4,19 @@
module sync module sync
//[init_with=new_waitgroup] // TODO: implement support for init_with struct attribute, and disallow WaitGroup{} from outside the sync.new_waitgroup() function.
pub struct WaitGroup { pub struct WaitGroup {
mut: mut:
mu Mutex mu Mutex
active int active int
} }
pub fn new_waitgroup() WaitGroup {
mut w := WaitGroup{}
w.mu = sync.new_mutex()
return w
}
pub fn (wg mut WaitGroup) add(delta int) { pub fn (wg mut WaitGroup) add(delta int) {
wg.mu.lock() wg.mu.lock()
wg.active += delta wg.active += delta