1/* BEGIN LICENSE BLOCK
2 * Version: CMPL 1.1
3 *
4 * The contents of this file are subject to the Cisco-style Mozilla Public
5 * License Version 1.1 (the "License"); you may not use this file except
6 * in compliance with the License.  You may obtain a copy of the License
7 * at www.eclipse-clp.org/license.
8 *
9 * Software distributed under the License is distributed on an "AS IS"
10 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
11 * the License for the specific language governing rights and limitations
12 * under the License.
13 *
14 * The Original Code is  The ECLiPSe Constraint Logic Programming System.
15 * The Initial Developer of the Original Code is  Cisco Systems, Inc.
16 * Portions created by the Initial Developer are
17 * Copyright (C) 1994-2006 Cisco Systems, Inc.  All Rights Reserved.
18 *
19 * Contributor(s): Joachim Schimpf, ECRC.
20 * Contributor(s): Kees Schuerman, ECRC.
21 *
22 * END LICENSE BLOCK */
23
24/*---------------------------------------------------------------------
25 * IDENTIFICATION	mutex.c
26 *
27 * CONTENTS		Code for spin locks
28 *---------------------------------------------------------------------*/
29
30#include "config.h"
31#include "memman.h"
32
33/*---------------------------------------------------------------------
34 * mutex_lock_failed() is normally implemented in assembler
35 * using an atomic test-and-set instruction (lock.S)
36 *---------------------------------------------------------------------*/
37
38#if (defined(lint) || defined(__APPLE__) || !(defined(m88k) || defined(sparc) || defined(mc68000) || defined(i386) || defined(mips) || defined(__alpha__) || defined(_PA_RISC1_0) || defined(_PA_RISC1_1)))
39
40int
41mutex_lock_failed(plock)	/* dummy (not atomic) */
42a_mutex_t *plock;
43{
44    if (*plock)
45	return 1;
46    *plock = 1;
47    return 0;
48}
49
50#endif
51
52/*--------------------------------------------------*/
53#if (defined(_PA_RISC1_0) || defined(_PA_RISC1_1))
54/*--------------------------------------------------*/
55
56/*
57** 1. The HP wants a lock aligned at a 16-bytes boundary!
58**    We have an array of 4 ints and use the one that is aligned.
59** 2. Locked = 0 ; Unlocked = 1
60*/
61
62#define RealLock(arr)	(&(arr)[3] - (unsigned)(&(arr)[3] - (int*)0) % 4)
63
64a_mutex_lock(mutex)
65volatile a_mutex_t *mutex;
66{
67    volatile int *plock = RealLock(*mutex);
68    Disable_Int();
69    while (mutex_lock_failed(plock))
70    {
71	Enable_Int();
72	while (!(*plock))
73	    continue;
74	Disable_Int();
75    }
76}
77
78a_mutex_unlock(mutex)
79a_mutex_t *mutex;
80{
81    int *plock = RealLock(*mutex);
82#ifdef PRINTAM
83    if (*plock) {
84	(void) write(2, "INTERNAL ERROR: unlocking unlocked mutex\n", 41);
85    }
86#endif
87    *plock = ~0;
88    Enable_Int();
89}
90
91a_mutex_init(mutex)
92a_mutex_t *mutex;
93{
94    *RealLock(*mutex) = ~0;
95}
96
97a_mutex_destroy(mutex)
98a_mutex_t *mutex;
99{
100    *RealLock(*mutex) = ~0;
101}
102
103/*--------------------------------------------------*/
104#else
105/*--------------------------------------------------*/
106
107a_mutex_lock(plock)
108volatile a_mutex_t *plock;
109{
110    Disable_Int();
111    while (mutex_lock_failed(plock))
112    {
113	Enable_Int();
114	while (*plock)
115	    continue;
116	Disable_Int();
117    }
118}
119
120a_mutex_unlock(plock)
121a_mutex_t *plock;
122{
123#ifdef PRINTAM
124    if (*plock == 0) {
125	(void) write(2, "INTERNAL ERROR: unlocking unlocked mutex\n", 41);
126    }
127#endif
128    *plock = 0;
129    Enable_Int();
130}
131
132a_mutex_init(plock)
133a_mutex_t *plock;
134{
135    *plock = 0;
136}
137
138a_mutex_destroy(plock)
139a_mutex_t *plock;
140{
141    *plock = 0;
142}
143
144#endif
145