-
Notifications
You must be signed in to change notification settings - Fork 3
/
sem.go
103 lines (92 loc) · 3.68 KB
/
sem.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// Copyright (c) 2020 Meng Huang (mhboy@outlook.com)
// This package is licensed under a MIT license that can be found in the LICENSE file.
package ipc
import (
"github.com/hslam/sem"
"unsafe"
)
// Sembuf represents an operation.
type Sembuf struct {
SemNum uint16
SemOp int16
SemFlg int16
}
// Semget calls the semget system call.
//
// The semget() system call returns the System V semaphore set identifier
// associated with the argument key.
//
// A new set of nsems semaphores is created if key has the value
// IPC_PRIVATE or if no existing semaphore set is associated with key
// and IPC_CREAT is specified in semflg.
//
// If semflg specifies both IPC_CREAT and IPC_EXCL and a semaphore set
// already exists for key, then semget() fails with errno set to EEXIST.
//
// The argument nsems can be 0 (a don't care) when a semaphore set is
// not being created. Otherwise, nsems must be greater than 0 and less
// than or equal to the maximum number of semaphores per semaphore set.
//
// If successful, the return value will be the semaphore set identifier,
// otherwise, -1 is returned, with errno indicating the error.
func Semget(key int, nsems int, semflg int) (int, error) {
return sem.Get(key, nsems, semflg)
}
// Semsetvalue calls the semctl SETVAL system call.
func Semsetvalue(semid int, semnum int, semun int) (bool, error) {
return sem.SetValue(semid, semnum, semun)
}
// Semgetvalue calls the semctl GETVAL system call.
func Semgetvalue(semid int, semnum int) (int, error) {
return sem.GetValue(semid, semnum)
}
// Semp calls the semop P system call.
// Flags recognized in semflg are IPC_NOWAIT and SEM_UNDO.
// If an operation specifies SEM_UNDO, it will be automatically undone when the
// process terminates.
func Semp(semid int, semnum int, semflg int) (bool, error) {
return sem.P(semid, semnum, semflg)
}
// Semv calls the semop V system call.
// Flags recognized in semflg are IPC_NOWAIT and SEM_UNDO.
// If an operation specifies SEM_UNDO, it will be automatically undone when the
// process terminates.
func Semv(semid int, semnum int, semflg int) (bool, error) {
return sem.V(semid, semnum, semflg)
}
// Semop calls the semop system call.
//
// semop() performs operations on selected semaphores in the set indi‐
// cated by semid. Each of the nsops elements in the array pointed to
// by sops is a structure that specifies an operation to be performed on
// a single semaphore. The elements of this structure are of type
// struct sembuf, containing the following members:
//
// unsigned short sem_num; /* semaphore number */
// short sem_op; /* semaphore operation */
// short sem_flg; /* operation flags */
//
// Flags recognized in sem_flg are IPC_NOWAIT and SEM_UNDO.
// If an operation specifies SEM_UNDO, it will be automatically undone when the
// process terminates.
//
// The set of operations contained in sops is performed in array order,
// and atomically, that is, the operations are performed either as a
// complete unit, or not at all. The behavior of the system call if not
// all operations can be performed immediately depends on the presence
// of the IPC_NOWAIT flag in the individual sem_flg fields, as noted be‐
// low.
func Semop(semid int, sops uintptr, nsops int) (bool, error) {
return sem.Op(semid, sops, nsops)
}
// Semoperate calls the semop system call.
// Flags recognized in SemFlg are IPC_NOWAIT and SEM_UNDO.
// If an operation specifies SEM_UNDO, it will be automatically undone when the
// process terminates.
func Semoperate(semid int, sops []Sembuf) (bool, error) {
return Semop(semid, uintptr(unsafe.Pointer(&sops[0])), len(sops))
}
// Semrm removes the semaphore with the given id.
func Semrm(semid int) error {
return sem.Remove(semid)
}