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.
30 * Copyright (c) 2012, Intel Corporation.
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
111 // EDX = v ; [EDX][0] = v->counter
115 lock sub dword ptr [edx][0], ecx
121 int __declspec (naked) FASTCALL
126 // ECX = v ; [ECX][0] = v->counter
130 lock inc dword ptr [ecx][0]
136 int __declspec (naked) FASTCALL
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)));
197 counter = v->counter;
198 result = counter - i;
200 } while ( InterlockedCompareExchange(
203 counter) != counter);
205 return (result == 0);
217 counter = v->counter;
218 result = counter + 1;
220 } while ( InterlockedCompareExchange(
223 counter) != counter);
225 return (result == 0);
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 atomic_add_return(int i, 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 atomic_sub_return(int i, atomic_t *v)
288 return atomic_add_return(-i, v);
291 int FASTCALL atomic_dec_and_lock(atomic_t *v, spinlock_t *lock)
293 if (atomic_read(v) != 1)
297 if (atomic_dec_and_test(v))
310 rwlock_init(rwlock_t *rwlock)
312 spin_lock_init(&rwlock->guard);
317 cfs_rwlock_fini(rwlock_t *rwlock)
322 read_lock(rwlock_t *rwlock)
324 struct task_struct * task = current;
325 PTASK_SLOT slot = NULL;
328 /* should bugchk here */
329 cfs_enter_debugger();
333 slot = CONTAINING_RECORD(task, TASK_SLOT, task);
334 ASSERT(slot->Magic == TASKSLT_MAGIC);
336 slot->irql = KeRaiseIrqlToDpcLevel();
339 spin_lock(&rwlock->guard);
340 if (rwlock->count >= 0)
342 spin_unlock(&rwlock->guard);
346 spin_unlock(&rwlock->guard);
350 read_unlock(rwlock_t *rwlock)
352 struct task_struct * task = current;
353 PTASK_SLOT slot = NULL;
356 /* should bugchk here */
357 cfs_enter_debugger();
361 slot = CONTAINING_RECORD(task, TASK_SLOT, task);
362 ASSERT(slot->Magic == TASKSLT_MAGIC);
364 spin_lock(&rwlock->guard);
365 ASSERT(rwlock->count > 0);
368 cfs_enter_debugger();
369 spin_unlock(&rwlock->guard);
371 KeLowerIrql(slot->irql);
375 write_lock(rwlock_t *rwlock)
377 struct task_struct * task = 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 spin_lock(&rwlock->guard);
393 if (rwlock->count == 0)
395 spin_unlock(&rwlock->guard);
399 spin_unlock(&rwlock->guard);
403 write_unlock(rwlock_t *rwlock)
405 struct task_struct * task = 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 spin_lock(&rwlock->guard);
418 ASSERT(rwlock->count == -1);
420 spin_unlock(&rwlock->guard);
422 KeLowerIrql(slot->irql);