/* Semaphore control operation. */ int semctl(int semid, int semnum, int cmd, ...) { kipc_msg_t m; endpoint_t ipc_pt; va_list ap; int r; if (get_ipc_endpt(&ipc_pt) != 0) { errno = -ENOSYS; return -1; } m.SEMCTL_ID = semid; m.SEMCTL_NUM = semnum; m.SEMCTL_CMD = cmd; va_start(ap, cmd); if (cmd == IPC_STAT || cmd == IPC_SET || cmd == IPC_INFO || cmd == SEM_INFO || cmd == SEM_STAT || cmd == GETALL || cmd == SETALL || cmd == SETVAL) m.SEMCTL_OPT = (long) va_arg(ap, long); va_end(ap); r = ktaskcall(ipc_pt, IPC_SEMCTL, &m); if ((r != -1) && (cmd == GETNCNT || cmd == GETZCNT || cmd == GETPID || cmd == GETVAL || cmd == IPC_INFO || cmd == SEM_INFO || cmd == SEM_STAT)) return m.SHMCTL_RET; return r; }
/* Semaphore control operation. */ int semctl(int semid, int semnum, int cmd, ...) { message m; endpoint_t ipc_pt; va_list ap; int r; if (get_ipc_endpt(&ipc_pt) != OK) { errno = ENOSYS; return -1; } memset(&m, 0, sizeof(m)); m.m_lc_ipc_semctl.id = semid; m.m_lc_ipc_semctl.num = semnum; m.m_lc_ipc_semctl.cmd = cmd; va_start(ap, cmd); if (cmd == IPC_STAT || cmd == IPC_SET || cmd == IPC_INFO || cmd == SEM_INFO || cmd == SEM_STAT || cmd == GETALL || cmd == SETALL || cmd == SETVAL) m.m_lc_ipc_semctl.opt = (long) va_arg(ap, long); va_end(ap); r = _syscall(ipc_pt, IPC_SEMCTL, &m); if ((r != -1) && (cmd == GETNCNT || cmd == GETZCNT || cmd == GETPID || cmd == GETVAL || cmd == IPC_INFO || cmd == SEM_INFO || cmd == SEM_STAT)) return m.m_lc_ipc_semctl.ret; return r; }
/* generic ipc futex caller, depending on action: * FUTEX_CREAT - creates futex and sets it's ipc_id * FUTEX_RMID - destroys futex * FUTEX_WAIT - atomically checks if futex has WAITING value and if so puts caller * into waiting queue, otherwise returns * FUTEX_SIGNAL - wakeup up to one waiting process * --- * returns 0 on success, other value on error */ PRIVATE int ipc_futex_call(futex_t* futex, int action) { message m; endpoint_t ipc_pt; int r; if (get_ipc_endpt(&ipc_pt) != OK) { errno = ENOSYS; return -1; } m.FUTEX_ID = futex->ipc_id; m.FUTEX_ADDR = (int) &futex->val; m.FUTEX_VAL = WAITING; m.FUTEX_OPS = action; r = _syscall(ipc_pt, IPC_FUTEX, &m); if (r != OK) { errno = r; return -1; } else if (m.m_type != OK) { errno = m.m_type; return -1; } if (action == FUTEX_CREAT) { assert(m.FUTEX_ID >= 0); futex->ipc_id = m.FUTEX_ID; } return 0; }
/* process is waiting on futex */ PRIVATE int futex_wait(futex_t *f) { message m; endpoint_t ipc_pt; if(get_ipc_endpt(&ipc_pt) != OK) { errno = ENOSYS; return -1; } m.FUTEX_ID = f->id; m.FUTEX_VALADR = (long)&f->val; return _syscall(ipc_pt, IPC_FUTLOCKADD, &m); }
/* destroying futex */ PUBLIC int futex_destroy(futex_t *f) { message m; endpoint_t ipc_pt; if(get_ipc_endpt(&ipc_pt) != OK) { errno = ENOSYS; return -1; } m.FUTEX_ID = f->id; return _syscall(ipc_pt, IPC_FUTDESTROY, &m); }
/* waking up one process waiting on futex */ PRIVATE int futex_wake(futex_t *f) { message m; endpoint_t ipc_pt; if(get_ipc_endpt(&ipc_pt) != OK) { errno = ENOSYS; return -1; } m.FUTEX_ID = f->id; return _syscall(ipc_pt, IPC_FUTUNLOCKWAKE, &m); }
/* Deattach shared memory segment. */ int shmdt(const void *shmaddr) { message m; endpoint_t ipc_pt; if (get_ipc_endpt(&ipc_pt) != OK) { errno = ENOSYS; return -1; } m.SHMDT_ADDR = (long) shmaddr; return _syscall(ipc_pt, IPC_SHMDT, &m); }
/* Operate on semaphore. */ int semop(int semid, struct sembuf *sops, size_t nsops) { kipc_msg_t m; endpoint_t ipc_pt; if (get_ipc_endpt(&ipc_pt) != 0) { errno = -ENOSYS; return -1; } m.SEMOP_ID = semid; m.SEMOP_OPS = (long) sops; m.SEMOP_SIZE = nsops; return ktaskcall(ipc_pt, IPC_SEMOP, &m); }
/* Operate on semaphore. */ int semop(int semid, struct sembuf *sops, size_t nsops) { message m; endpoint_t ipc_pt; if (get_ipc_endpt(&ipc_pt) != OK) { errno = ENOSYS; return -1; } m.SEMOP_ID = semid; m.SEMOP_OPS = (long) sops; m.SEMOP_SIZE = nsops; return _syscall(ipc_pt, IPC_SEMOP, &m); }
/* Operate on semaphore. */ int semop(int semid, struct sembuf *sops, size_t nsops) { message m; endpoint_t ipc_pt; if (get_ipc_endpt(&ipc_pt) != OK) { errno = ENOSYS; return -1; } memset(&m, 0, sizeof(m)); m.m_lc_ipc_semop.id = semid; m.m_lc_ipc_semop.ops = sops; m.m_lc_ipc_semop.size = nsops; return _syscall(ipc_pt, IPC_SEMOP, &m); }
/* initialising futex */ PUBLIC int futex_init(futex_t *f) { message m; endpoint_t ipc_pt; if(get_ipc_endpt(&ipc_pt) != OK) { errno = ENOSYS; return -1; } if(_syscall(ipc_pt, IPC_FUTINIT, &m) != OK) { errno = ENOSYS; return -1; } f->id = m.FUTEX_ID; f->val = 0; return OK; }
/* Attach shared memory segment. */ void *shmat(int shmid, const void *shmaddr, int shmflg) { message m; endpoint_t ipc_pt; int r; if (get_ipc_endpt(&ipc_pt) != OK) { errno = ENOSYS; return NULL; } m.SHMAT_ID = shmid; m.SHMAT_ADDR = (long) shmaddr; m.SHMAT_FLAG = shmflg; r = _syscall(ipc_pt, IPC_SHMAT, &m); if (r != OK) return (void *) -1; return (void *) m.SHMAT_RETADDR; }
/* Get shared memory segment. */ int shmget(key_t key, size_t size, int shmflg) { message m; endpoint_t ipc_pt; int r; if (get_ipc_endpt(&ipc_pt) != OK) { errno = ENOSYS; return -1; } m.SHMGET_KEY = key; m.SHMGET_SIZE = size; m.SHMGET_FLAG = shmflg; r = _syscall(ipc_pt, IPC_SHMGET, &m); if (r != OK) return r; return m.SHMGET_RETID; }
/* Get semaphore. */ int semget(key_t key, int nsems, int semflag) { kipc_msg_t m; endpoint_t ipc_pt; int r; if (get_ipc_endpt(&ipc_pt) != 0) { errno = -ENOSYS; return -1; } m.SEMGET_KEY = key; m.SEMGET_NR = nsems; m.SEMGET_FLAG = semflag; r = ktaskcall(ipc_pt, IPC_SEMGET, &m); if (r != 0) return r; return m.SEMGET_RETID; }
/* Get semaphore. */ int semget(key_t key, int nsems, int semflag) { message m; endpoint_t ipc_pt; int r; if (get_ipc_endpt(&ipc_pt) != OK) { errno = ENOSYS; return -1; } m.SEMGET_KEY = key; m.SEMGET_NR = nsems; m.SEMGET_FLAG = semflag; r = _syscall(ipc_pt, IPC_SEMGET, &m); if (r != OK) return r; return m.SEMGET_RETID; }
/* Get semaphore. */ int semget(key_t key, int nsems, int semflag) { message m; endpoint_t ipc_pt; int r; if (get_ipc_endpt(&ipc_pt) != OK) { errno = ENOSYS; return -1; } memset(&m, 0, sizeof(m)); m.m_lc_ipc_semget.key = key; m.m_lc_ipc_semget.nr = nsems; m.m_lc_ipc_semget.flag = semflag; r = _syscall(ipc_pt, IPC_SEMGET, &m); if (r != OK) return r; return m.m_lc_ipc_semget.retid; }