~ubuntu-branches/ubuntu/utopic/gridengine/utopic

« back to all changes in this revision

Viewing changes to source/libs/lck/test_sge_deadlock.c

  • Committer: Bazaar Package Importer
  • Author(s): Mark Hymers
  • Date: 2008-06-25 22:36:13 UTC
  • Revision ID: james.westby@ubuntu.com-20080625223613-tvd9xlhuoct9kyhm
Tags: upstream-6.2~beta2
ImportĀ upstreamĀ versionĀ 6.2~beta2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*___INFO__MARK_BEGIN__*/
 
2
/*************************************************************************
 
3
 * 
 
4
 *  The Contents of this file are made available subject to the terms of
 
5
 *  the Sun Industry Standards Source License Version 1.2
 
6
 * 
 
7
 *  Sun Microsystems Inc., March, 2001
 
8
 * 
 
9
 * 
 
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
 
16
 * 
 
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.
 
23
 * 
 
24
 *   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 
25
 * 
 
26
 *   Copyright: 2003 by Sun Microsystems, Inc.
 
27
 * 
 
28
 *   All Rights Reserved.
 
29
 * 
 
30
 ************************************************************************/
 
31
/*___INFO__MARK_END__*/
 
32
 
 
33
#include "test_sge_lock_main.h"
 
34
 
 
35
#include <unistd.h>
 
36
#include <stdio.h>
 
37
#include "sge_lock.h"
 
38
 
 
39
 
 
40
static void *thread_function_1(void *anArg);
 
41
static void *thread_function_2(void *anArg);
 
42
 
 
43
int get_thrd_demand(void)
 
44
{
 
45
   long p = 2;  /* min num of threads */
 
46
 
 
47
#if defined(SOLARIS)
 
48
   p = sysconf(_SC_NPROCESSORS_ONLN);
 
49
#endif
 
50
 
 
51
   return (int)p;
 
52
}
 
53
 
 
54
void *(*get_thrd_func(void))(void *anArg)
 
55
{
 
56
   static int i = 0;
 
57
 
 
58
   return ((i++ % 2) ? thread_function_1 : thread_function_2) ;
 
59
}
 
60
 
 
61
void *get_thrd_func_arg(void)
 
62
{
 
63
   return NULL;
 
64
}
 
65
 
 
66
/****** test_sge_lock_simple/thread_function_1() *********************************
 
67
*  NAME
 
68
*     thread_function_1() -- Thread function to execute 
 
69
*
 
70
*  SYNOPSIS
 
71
*     static void* thread_function_1(void *anArg) 
 
72
*
 
73
*  FUNCTION
 
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. 
 
76
*
 
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()'.
 
80
*
 
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.
 
85
*
 
86
*     This example does reveal how important it is to obey a GLOBAL acquire/release
 
87
*     protocol. 
 
88
*
 
89
*  INPUTS
 
90
*     void *anArg - thread function arguments 
 
91
*
 
92
*  RESULT
 
93
*     static void* - none
 
94
*
 
95
*  SEE ALSO
 
96
*     test_sge_deadlock/get_thrd_func()
 
97
*     test_sge_deadlock/thread_function_2()
 
98
*******************************************************************************/
 
99
static void *thread_function_1(void *anArg)
 
100
{
 
101
   DENTER(TOP_LAYER, "thread_function");
 
102
 
 
103
   SGE_LOCK(LOCK_GLOBAL, LOCK_READ);
 
104
   sleep(3);
 
105
 
 
106
   SGE_LOCK(LOCK_MASTER_PROJECT_LST, LOCK_READ);
 
107
   sleep(3);
 
108
 
 
109
   DPRINTF(("Thread %u sleeping\n", sge_locker_id()));
 
110
   sleep(5);
 
111
 
 
112
   SGE_UNLOCK(LOCK_MASTER_PROJECT_LST, LOCK_READ);
 
113
   sleep(3);
 
114
 
 
115
   SGE_UNLOCK(LOCK_GLOBAL, LOCK_READ);
 
116
   sleep(3);
 
117
 
 
118
   DEXIT;
 
119
   return (void *)NULL;
 
120
} /* thread_function_1 */
 
121
 
 
122
/****** test_sge_deadlock/thread_function_2() **********************************
 
123
*  NAME
 
124
*     thread_function_2() -- Thread function to execute
 
125
*
 
126
*  SYNOPSIS
 
127
*     static void* thread_function_2(void *anArg) 
 
128
*
 
129
*  FUNCTION
 
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. 
 
132
*
 
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()'.
 
136
*
 
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.
 
141
*
 
142
*     This example does reveal how important it is to obey a GLOBAL acquire/release
 
143
*     protocol. 
 
144
*
 
145
*  INPUTS
 
146
*     void *anArg - thread function arguments
 
147
*
 
148
*  RESULT
 
149
*     static void* - none
 
150
*
 
151
*  SEE ALSO
 
152
*     test_sge_deadlock/get_thrd_func()
 
153
*     test_sge_deadlock/thread_function_1()
 
154
*******************************************************************************/
 
155
static void *thread_function_2(void *anArg)
 
156
{
 
157
   DENTER(TOP_LAYER, "thread_function");
 
158
 
 
159
   SGE_LOCK(LOCK_MASTER_PROJECT_LST, LOCK_READ);
 
160
   sleep(3);
 
161
 
 
162
   SGE_LOCK(LOCK_GLOBAL, LOCK_READ);
 
163
   sleep(3);
 
164
 
 
165
   DPRINTF(("Thread %u sleeping\n", sge_locker_id()));
 
166
   sleep(5);
 
167
 
 
168
   SGE_UNLOCK(LOCK_GLOBAL, LOCK_READ);
 
169
   sleep(3);
 
170
 
 
171
   SGE_UNLOCK(LOCK_MASTER_PROJECT_LST, LOCK_READ);
 
172
   sleep(3);
 
173
 
 
174
   DEXIT;
 
175
   return (void *)NULL;
 
176
} /* thread_function_2 */