1
/*___INFO__MARK_BEGIN__*/
2
/*************************************************************************
4
* The Contents of this file are made available subject to the terms of
5
* the Sun Industry Standards Source License Version 1.2
7
* Sun Microsystems Inc., March, 2001
10
* Sun Industry Standards Source License Version 1.2
11
* =================================================
12
* The contents of this file are subject to the Sun Industry Standards
13
* Source License Version 1.2 (the "License"); You may not use this file
14
* except in compliance with the License. You may obtain a copy of the
15
* License at http://gridengine.sunsource.net/Gridengine_SISSL_license.html
17
* Software provided under this License is provided on an "AS IS" basis,
18
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
19
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
20
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
21
* See the License for the specific provisions governing your rights and
22
* obligations concerning the Software.
24
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
26
* Copyright: 2003 by Sun Microsystems, Inc.
28
* All Rights Reserved.
30
************************************************************************/
31
/*___INFO__MARK_END__*/
33
#include "test_sge_lock_main.h"
40
static void *thread_function_1(void *anArg);
41
static void *thread_function_2(void *anArg);
43
int get_thrd_demand(void)
45
long p = 2; /* min num of threads */
48
p = sysconf(_SC_NPROCESSORS_ONLN);
54
void *(*get_thrd_func(void))(void *anArg)
58
return ((i++ % 2) ? thread_function_1 : thread_function_2) ;
61
void *get_thrd_func_arg(void)
66
/****** test_sge_lock_simple/thread_function_1() *********************************
68
* thread_function_1() -- Thread function to execute
71
* static void* thread_function_1(void *anArg)
74
* Acquire multiple locks and sleep. Release the locks. After each 'sge_lock()'
75
* and 'sge_unlock()' sleep to increase the probability of interlocked execution.
77
* Note: This function for itself is perfectly reasonable. However, a race
78
* condition, and thus a potential deadlock, does emerge if this function is
79
* run in parallel with 'thread_function_2()'.
81
* The reason for this is, that 'thread_function_1()' and 'thread_function_2()'
82
* each follow their own local acquire/release protocol. As a consequence,
83
* 'thread_function_1()' and 'thread_function_2()' acquire and release their
84
* respective locks in different orders.
86
* This example does reveal how important it is to obey a GLOBAL acquire/release
90
* void *anArg - thread function arguments
96
* test_sge_deadlock/get_thrd_func()
97
* test_sge_deadlock/thread_function_2()
98
*******************************************************************************/
99
static void *thread_function_1(void *anArg)
101
DENTER(TOP_LAYER, "thread_function");
103
SGE_LOCK(LOCK_GLOBAL, LOCK_READ);
106
SGE_LOCK(LOCK_MASTER_PROJECT_LST, LOCK_READ);
109
DPRINTF(("Thread %u sleeping\n", sge_locker_id()));
112
SGE_UNLOCK(LOCK_MASTER_PROJECT_LST, LOCK_READ);
115
SGE_UNLOCK(LOCK_GLOBAL, LOCK_READ);
120
} /* thread_function_1 */
122
/****** test_sge_deadlock/thread_function_2() **********************************
124
* thread_function_2() -- Thread function to execute
127
* static void* thread_function_2(void *anArg)
130
* Acquire multiple locks and sleep. Release the locks. After each 'sge_lock()'
131
* and 'sge_unlock()' sleep to increase the probability of interlocked execution.
133
* Note: This function for itself is perfectly reasonable. However, a race
134
* condition, and thus a potential deadlock, does emerge if this function is
135
* run in parallel with 'thread_function_1()'.
137
* The reason for this is, that 'thread_function_2()' and 'thread_function_1()'
138
* each follow their own local acquire/release protocol. As a consequence,
139
* 'thread_function_2()' and 'thread_function_1()' acquire and release their
140
* respective locks in different orders.
142
* This example does reveal how important it is to obey a GLOBAL acquire/release
146
* void *anArg - thread function arguments
149
* static void* - none
152
* test_sge_deadlock/get_thrd_func()
153
* test_sge_deadlock/thread_function_1()
154
*******************************************************************************/
155
static void *thread_function_2(void *anArg)
157
DENTER(TOP_LAYER, "thread_function");
159
SGE_LOCK(LOCK_MASTER_PROJECT_LST, LOCK_READ);
162
SGE_LOCK(LOCK_GLOBAL, LOCK_READ);
165
DPRINTF(("Thread %u sleeping\n", sge_locker_id()));
168
SGE_UNLOCK(LOCK_GLOBAL, LOCK_READ);
171
SGE_UNLOCK(LOCK_MASTER_PROJECT_LST, LOCK_READ);
176
} /* thread_function_2 */