5
/* $Id: threads.c,v 1.1.2.5 2007-08-28 21:29:46 manoj Exp $ */
8
# define PRNDBG3(m,a1,a2,a3) \
9
fprintf(stderr,"DBG %d: " m,armci_me,a1,a2,a3);fflush(stderr)
10
# define PRNDBG(m) PRNDBG3(m,0,0,0)
11
# define PRNDBG1(m,a1) PRNDBG3(m,a1,0,0)
12
# define PRNDBG2(m,a1,a2) PRNDBG3(m,a1,a2,0)
15
# define PRNDBG1(m,a1)
16
# define PRNDBG2(m,a1,a2)
17
# define PRNDBG3(m,a1,a2,a3)
24
armci_user_threads_t armci_user_threads;
26
void armci_init_threads()
29
char *uval = getenv("ARMCI_MAX_THREADS");
31
armci_user_threads.max = 1;
32
armci_user_threads.avail = 0;
34
if (uval != NULL) sscanf(uval, "%d", &armci_user_threads.max);
36
if (armci_user_threads.max < 1 ||
37
armci_user_threads.max > ARMCI_THREADS_LIMIT)
39
printf("Error: Only 1-%d threads are supported. ",ARMCI_THREADS_LIMIT);
40
printf("Set ARMCI_MAX_THREADS appropriately\n"); fflush(stdout);
41
armci_die("armci_init_threads: failed", 0);
44
bytes = sizeof(thread_id_t) * armci_user_threads.max;
45
if ( !(armci_user_threads.ids = (thread_id_t*) malloc(bytes)) )
47
armci_die("armci_init_threads: armci_user_threads.ids malloc failed",
48
armci_user_threads.max);
50
memset(armci_user_threads.ids, 0, bytes);
52
#if 0 /* spinlock has void return value */
53
if (THREAD_LOCK_INIT(armci_user_threads.lock) ||
54
THREAD_LOCK_INIT(armci_user_threads.buf_lock) ||
55
THREAD_LOCK_INIT(armci_user_threads.net_lock))
56
armci_die("armci_init_threads:locks initialization failed", 0);
58
THREAD_LOCK_INIT(armci_user_threads.lock);
59
THREAD_LOCK_INIT(armci_user_threads.buf_lock);
60
THREAD_LOCK_INIT(armci_user_threads.net_lock);
64
/* using one lock per socket for now, it might be feasible (and usefull)
65
* to use two (one for sending and one for receiving) */
66
armci_user_threads.sock_locks = malloc(armci_nclus *sizeof(thread_lock_t));
67
for (i = 0; i < armci_nclus; i++)
68
if (THREAD_LOCK_INIT(armci_user_threads.sock_locks[i]))
69
armci_die("armci_init_threads:sock locks initialization failed", i);
73
void armci_finalize_threads()
75
THREAD_LOCK_DESTROY(armci_user_threads.lock);
76
THREAD_LOCK_DESTROY(armci_user_threads.net_lock);
77
THREAD_LOCK_DESTROY(armci_user_threads.buf_lock);
78
free(armci_user_threads.ids);
81
/* calling armci_thread_idx for every function that accesses thread-private data
82
* might be expensive -- needs optiomization */
83
INLINE int armci_thread_idx()
85
int i, n = ARMCI_MIN(armci_user_threads.avail, armci_user_threads.max);
86
thread_id_t id = THREAD_ID_SELF();
88
for (i = 0; i < n; i++) if (id == armci_user_threads.ids[i]) {
89
/*PRNDBG2("thread id=%ld already registered, idx=%d\n", id, i);*/
93
/* see this thread for the first time */
94
return armci_register_thread(id);
97
INLINE int armci_register_thread(thread_id_t id)
101
THREAD_LOCK(armci_user_threads.lock);
103
i = armci_user_threads.avail;
104
armci_user_threads.avail++;
106
THREAD_UNLOCK(armci_user_threads.lock);
108
if (i < armci_user_threads.max)
109
armci_user_threads.ids[i] = id;
111
armci_die("armci_thread_idx: too many threads, adjust ARMCI_MAX_THREADS",
112
armci_user_threads.avail);
114
PRNDBG2("registered a new thread: idx=%d, id=%ld\n", i, id);