1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
30 * Use is subject to license terms.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
38 # define DEBUG_SUBSYSTEM S_LNET
40 #include <libcfs/libcfs.h>
45 void __declspec (naked) FASTCALL
52 // EDX = v ; [EDX][0] = v->counter
55 lock add dword ptr [edx][0], ecx
60 void __declspec (naked) FASTCALL
67 // EDX = v ; [EDX][0] = v->counter
70 lock sub dword ptr [edx][0], ecx
75 void __declspec (naked) FASTCALL
80 //InterlockedIncrement((PULONG)(&((v)->counter)));
82 //` ECX = v ; [ECX][0] = v->counter
85 lock inc dword ptr [ecx][0]
90 void __declspec (naked) FASTCALL
95 // ECX = v ; [ECX][0] = v->counter
98 lock dec dword ptr [ecx][0]
103 int __declspec (naked) FASTCALL
104 cfs_atomic_sub_and_test(
111 // EDX = v ; [EDX][0] = v->counter
115 lock sub dword ptr [edx][0], ecx
121 int __declspec (naked) FASTCALL
122 cfs_atomic_inc_and_test(
126 // ECX = v ; [ECX][0] = v->counter
130 lock inc dword ptr [ecx][0]
136 int __declspec (naked) FASTCALL
137 cfs_atomic_dec_and_test(
141 // ECX = v ; [ECX][0] = v->counter
145 lock dec dword ptr [ecx][0]
151 #elif defined(_AMD64_)
159 InterlockedExchangeAdd( (PULONG)(&((v)->counter)) , (LONG) (i));
168 InterlockedExchangeAdd( (PULONG)(&((v)->counter)) , (LONG) (-1*i));
176 InterlockedIncrement((PULONG)(&((v)->counter)));
184 InterlockedDecrement((PULONG)(&((v)->counter)));
188 cfs_atomic_sub_and_test(
197 counter = v->counter;
198 result = counter - i;
200 } while ( InterlockedCompareExchange(
203 counter) != counter);
205 return (result == 0);
209 cfs_atomic_inc_and_test(
217 counter = v->counter;
218 result = counter + 1;
220 } while ( InterlockedCompareExchange(
223 counter) != counter);
225 return (result == 0);
229 cfs_atomic_dec_and_test(
237 counter = v->counter;
238 result = counter - 1;
240 } while ( InterlockedCompareExchange(
243 counter) != counter);
245 return (result == 0);
250 #error CPU arch type isn't specified.
255 * atomic_add_return - add integer and return
256 * \param v pointer of type atomic_t
257 * \param i integer value to add
259 * Atomically adds \a i to \a v and returns \a i + \a v
261 int FASTCALL cfs_atomic_add_return(int i, cfs_atomic_t *v)
267 counter = v->counter;
268 result = counter + i;
270 } while ( InterlockedCompareExchange(
273 counter) != counter);
280 * atomic_sub_return - subtract integer and return
281 * \param v pointer of type atomic_t
282 * \param i integer value to subtract
284 * Atomically subtracts \a i from \a v and returns \a v - \a i
286 int FASTCALL cfs_atomic_sub_return(int i, cfs_atomic_t *v)
288 return cfs_atomic_add_return(-i, v);
291 int FASTCALL cfs_atomic_dec_and_lock(cfs_atomic_t *v, cfs_spinlock_t *lock)
293 if (cfs_atomic_read(v) != 1) {
298 if (cfs_atomic_dec_and_test(v))
300 cfs_spin_unlock(lock);
311 cfs_rwlock_init(cfs_rwlock_t * rwlock)
313 cfs_spin_lock_init(&rwlock->guard);
318 cfs_rwlock_fini(cfs_rwlock_t * rwlock)
323 cfs_read_lock(cfs_rwlock_t * rwlock)
325 cfs_task_t * task = cfs_current();
326 PTASK_SLOT slot = NULL;
329 /* should bugchk here */
330 cfs_enter_debugger();
334 slot = CONTAINING_RECORD(task, TASK_SLOT, task);
335 ASSERT(slot->Magic == TASKSLT_MAGIC);
337 slot->irql = KeRaiseIrqlToDpcLevel();
340 cfs_spin_lock(&rwlock->guard);
341 if (rwlock->count >= 0)
343 cfs_spin_unlock(&rwlock->guard);
347 cfs_spin_unlock(&rwlock->guard);
351 cfs_read_unlock(cfs_rwlock_t * rwlock)
353 cfs_task_t * task = cfs_current();
354 PTASK_SLOT slot = NULL;
357 /* should bugchk here */
358 cfs_enter_debugger();
362 slot = CONTAINING_RECORD(task, TASK_SLOT, task);
363 ASSERT(slot->Magic == TASKSLT_MAGIC);
365 cfs_spin_lock(&rwlock->guard);
366 ASSERT(rwlock->count > 0);
369 cfs_enter_debugger();
371 cfs_spin_unlock(&rwlock->guard);
373 KeLowerIrql(slot->irql);
377 cfs_write_lock(cfs_rwlock_t * rwlock)
379 cfs_task_t * task = cfs_current();
380 PTASK_SLOT slot = NULL;
383 /* should bugchk here */
384 cfs_enter_debugger();
388 slot = CONTAINING_RECORD(task, TASK_SLOT, task);
389 ASSERT(slot->Magic == TASKSLT_MAGIC);
391 slot->irql = KeRaiseIrqlToDpcLevel();
394 cfs_spin_lock(&rwlock->guard);
395 if (rwlock->count == 0)
397 cfs_spin_unlock(&rwlock->guard);
401 cfs_spin_unlock(&rwlock->guard);
405 cfs_write_unlock(cfs_rwlock_t * rwlock)
407 cfs_task_t * task = cfs_current();
408 PTASK_SLOT slot = NULL;
411 /* should bugchk here */
412 cfs_enter_debugger();
416 slot = CONTAINING_RECORD(task, TASK_SLOT, task);
417 ASSERT(slot->Magic == TASKSLT_MAGIC);
419 cfs_spin_lock(&rwlock->guard);
420 ASSERT(rwlock->count == -1);
422 cfs_spin_unlock(&rwlock->guard);
424 KeLowerIrql(slot->irql);