1/*
2 * Copyright (c) 2011, ETH Zurich.
3 * All rights reserved.
4 *
5 * This file is distributed under the terms in the attached LICENSE file.
6 * If you do not find this file, copies can be found by writing to:
7 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
8 */
9
10#include <stdio.h>
11#include <errno.h>
12#include <semaphore.h>
13#include <assert.h>
14#include <barrelfish/barrelfish.h>
15#include <string.h>
16#include "posixcompat.h"
17
18#include <octopus/init.h>
19#include <octopus/semaphores.h>
20
21
22int sem_init(sem_t *sem, int pshared, unsigned int value)
23{
24    POSIXCOMPAT_DEBUG("sem_init(%p, %d, %u)\n", sem, pshared, value);
25
26    memset(sem, 0, sizeof(sem_t));
27
28    if(pshared != 0) {
29        oct_init();
30        sem->pshared = 1;
31        /* fprintf(stderr, "sem_init called with pshared != 0. Ignoring.\n"); */
32
33        POSIXCOMPAT_DEBUG("%d: sem_init(%p, %d, %u)\n", disp_get_domain_id(), sem, pshared, value);
34        //debug_printf("oct_sem_new\n");
35        errval_t err = oct_sem_new(&sem->id, value);
36        //debug_printf("sem->id now is: %d\n", sem->id);
37        if (err_is_fail(err)) {
38            USER_PANIC_ERR(err, "sem_new reterr");
39        }
40    } else {
41        sem->pshared = 0;
42        thread_sem_init(&sem->thread_sem, value);
43    }
44    return 0;
45}
46
47int sem_destroy(sem_t *sem)
48{
49    POSIXCOMPAT_DEBUG("sem_destroy(%p)\n", sem);
50    assert(!"NYI");
51    // Nothing needed
52    return 0;
53}
54
55int sem_wait(sem_t *sem)
56{
57  	POSIXCOMPAT_DEBUG("%d: sem_wait(%p, %u):\n %p %p %p %p\n", disp_get_domain_id(), sem, sem->id,
58	 __builtin_return_address(0),
59	 __builtin_return_address(1),
60	 __builtin_return_address(2),
61     __builtin_return_address(3));
62
63    if(!sem->pshared) {
64        thread_sem_wait(&sem->thread_sem);
65    } else {
66        oct_init();
67
68        errval_t err;
69        err = oct_sem_wait(sem->id);
70        if (err_is_fail(err)) {
71            USER_PANIC_ERR(err, "sem_wait");
72        }
73    }
74
75    return 0;
76}
77
78int sem_trywait(sem_t *sem)
79{
80	POSIXCOMPAT_DEBUG("%d: sem_trywait(%p, %u)\n", disp_get_domain_id(), sem, sem->id);
81
82    if(!sem->pshared) {
83        if(thread_sem_trywait(&sem->thread_sem)) {
84            return 0;
85        } else {
86            errno = EAGAIN;
87            return -1;
88        }
89    } else {
90        oct_init();
91
92        errval_t err = oct_sem_trywait(sem->id);
93        if (err_is_ok(err)) {
94	  		POSIXCOMPAT_DEBUG("%d: sem_trywait(%p, %u) success!\n", disp_get_domain_id(), sem, sem->id);
95            return 0;
96        }
97        else if (err_no(err) == OCT_ERR_NO_RECORD) {
98	  		POSIXCOMPAT_DEBUG("%d: sem_trywait(%p, %u) no success\n", disp_get_domain_id(), sem, sem->id);
99            errno = EAGAIN;
100            return -1;
101        }
102        else {
103            USER_PANIC_ERR(err, "sem_wait");
104        }
105    }
106
107    assert(!"Should not reach here");
108}
109
110int sem_post(sem_t *sem)
111{
112  	POSIXCOMPAT_DEBUG("%d: sem_post(%p, %u): %p %p %p %p\n", disp_get_domain_id(), sem, sem->id,
113	 __builtin_return_address(0),
114	 __builtin_return_address(1),
115	 __builtin_return_address(2),
116     __builtin_return_address(3));
117
118    if(!sem->pshared) {
119        thread_sem_post(&sem->thread_sem);
120    } else {
121        oct_init();
122
123        errval_t err;
124        err = oct_sem_post(sem->id);
125        if (err_is_fail(err)) {
126            USER_PANIC_ERR(err, "sem_post");
127        }
128    }
129
130    return 0;
131}
132