4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
31 * This file is part of Lustre, http://www.lustre.org/
32 * Lustre is a trademark of Sun Microsystems, Inc.
36 # define DEBUG_SUBSYSTEM S_LNET
38 #include <libcfs/libcfs.h>
43 void __declspec (naked) FASTCALL
50 // EDX = v ; [EDX][0] = v->counter
53 lock add dword ptr [edx][0], ecx
58 void __declspec (naked) FASTCALL
65 // EDX = v ; [EDX][0] = v->counter
68 lock sub dword ptr [edx][0], ecx
73 void __declspec (naked) FASTCALL
78 //InterlockedIncrement((PULONG)(&((v)->counter)));
80 //` ECX = v ; [ECX][0] = v->counter
83 lock inc dword ptr [ecx][0]
88 void __declspec (naked) FASTCALL
93 // ECX = v ; [ECX][0] = v->counter
96 lock dec dword ptr [ecx][0]
101 int __declspec (naked) FASTCALL
102 cfs_atomic_sub_and_test(
109 // EDX = v ; [EDX][0] = v->counter
113 lock sub dword ptr [edx][0], ecx
119 int __declspec (naked) FASTCALL
120 cfs_atomic_inc_and_test(
124 // ECX = v ; [ECX][0] = v->counter
128 lock inc dword ptr [ecx][0]
134 int __declspec (naked) FASTCALL
135 cfs_atomic_dec_and_test(
139 // ECX = v ; [ECX][0] = v->counter
143 lock dec dword ptr [ecx][0]
149 #elif defined(_AMD64_)
157 InterlockedExchangeAdd( (PULONG)(&((v)->counter)) , (LONG) (i));
166 InterlockedExchangeAdd( (PULONG)(&((v)->counter)) , (LONG) (-1*i));
174 InterlockedIncrement((PULONG)(&((v)->counter)));
182 InterlockedDecrement((PULONG)(&((v)->counter)));
186 cfs_atomic_sub_and_test(
195 counter = v->counter;
196 result = counter - i;
198 } while ( InterlockedCompareExchange(
201 counter) != counter);
203 return (result == 0);
207 cfs_atomic_inc_and_test(
215 counter = v->counter;
216 result = counter + 1;
218 } while ( InterlockedCompareExchange(
221 counter) != counter);
223 return (result == 0);
227 cfs_atomic_dec_and_test(
235 counter = v->counter;
236 result = counter - 1;
238 } while ( InterlockedCompareExchange(
241 counter) != counter);
243 return (result == 0);
248 #error CPU arch type isn't specified.
253 * atomic_add_return - add integer and return
254 * \param v pointer of type atomic_t
255 * \param i integer value to add
257 * Atomically adds \a i to \a v and returns \a i + \a v
259 int FASTCALL cfs_atomic_add_return(int i, cfs_atomic_t *v)
265 counter = v->counter;
266 result = counter + i;
268 } while ( InterlockedCompareExchange(
271 counter) != counter);
278 * atomic_sub_return - subtract integer and return
279 * \param v pointer of type atomic_t
280 * \param i integer value to subtract
282 * Atomically subtracts \a i from \a v and returns \a v - \a i
284 int FASTCALL cfs_atomic_sub_return(int i, cfs_atomic_t *v)
286 return cfs_atomic_add_return(-i, v);
289 int FASTCALL cfs_atomic_dec_and_lock(cfs_atomic_t *v, cfs_spinlock_t *lock)
291 if (cfs_atomic_read(v) != 1) {
296 if (cfs_atomic_dec_and_test(v))
298 cfs_spin_unlock(lock);
309 cfs_rwlock_init(cfs_rwlock_t * rwlock)
311 cfs_spin_lock_init(&rwlock->guard);
316 cfs_rwlock_fini(cfs_rwlock_t * rwlock)
321 cfs_read_lock(cfs_rwlock_t * rwlock)
323 cfs_task_t * task = cfs_current();
324 PTASK_SLOT slot = NULL;
327 /* should bugchk here */
328 cfs_enter_debugger();
332 slot = CONTAINING_RECORD(task, TASK_SLOT, task);
333 ASSERT(slot->Magic == TASKSLT_MAGIC);
335 slot->irql = KeRaiseIrqlToDpcLevel();
338 cfs_spin_lock(&rwlock->guard);
339 if (rwlock->count >= 0)
341 cfs_spin_unlock(&rwlock->guard);
345 cfs_spin_unlock(&rwlock->guard);
349 cfs_read_unlock(cfs_rwlock_t * rwlock)
351 cfs_task_t * task = cfs_current();
352 PTASK_SLOT slot = NULL;
355 /* should bugchk here */
356 cfs_enter_debugger();
360 slot = CONTAINING_RECORD(task, TASK_SLOT, task);
361 ASSERT(slot->Magic == TASKSLT_MAGIC);
363 cfs_spin_lock(&rwlock->guard);
364 ASSERT(rwlock->count > 0);
367 cfs_enter_debugger();
369 cfs_spin_unlock(&rwlock->guard);
371 KeLowerIrql(slot->irql);
375 cfs_write_lock(cfs_rwlock_t * rwlock)
377 cfs_task_t * task = cfs_current();
378 PTASK_SLOT slot = NULL;
381 /* should bugchk here */
382 cfs_enter_debugger();
386 slot = CONTAINING_RECORD(task, TASK_SLOT, task);
387 ASSERT(slot->Magic == TASKSLT_MAGIC);
389 slot->irql = KeRaiseIrqlToDpcLevel();
392 cfs_spin_lock(&rwlock->guard);
393 if (rwlock->count == 0)
395 cfs_spin_unlock(&rwlock->guard);
399 cfs_spin_unlock(&rwlock->guard);
403 cfs_write_unlock(cfs_rwlock_t * rwlock)
405 cfs_task_t * task = cfs_current();
406 PTASK_SLOT slot = NULL;
409 /* should bugchk here */
410 cfs_enter_debugger();
414 slot = CONTAINING_RECORD(task, TASK_SLOT, task);
415 ASSERT(slot->Magic == TASKSLT_MAGIC);
417 cfs_spin_lock(&rwlock->guard);
418 ASSERT(rwlock->count == -1);
420 cfs_spin_unlock(&rwlock->guard);
422 KeLowerIrql(slot->irql);