1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (c) 2002 Cray Inc.
5 * Copyright (c) 2003 Cluster File Systems, Inc.
7 * This file is part of Lustre, http://www.lustre.org.
9 * Lustre is free software; you can redistribute it and/or
10 * modify it under the terms of version 2 of the GNU General Public
11 * License as published by the Free Software Foundation.
13 * Lustre is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with Lustre; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 * This file provides the 'library' side for the process-based nals.
25 * it is responsible for communication with the 'api' side and
26 * providing service to the generic portals 'library'
27 * implementation. 'library' might be better termed 'communication'
35 #include <procbridge.h>
36 #include <sys/types.h>
37 #include <sys/socket.h>
43 /* the following functions are stubs to satisfy the nal definition
44 without doing anything particularily useful*/
46 static int nal_write(nal_cb_t *nal,
52 memcpy(dst_addr, src_addr, len);
56 static int nal_read(nal_cb_t * nal,
62 memcpy(dst_addr, src_addr, len);
66 static void *nal_malloc(nal_cb_t *nal,
69 void *buf = malloc(len);
73 static void nal_free(nal_cb_t *nal,
80 static void nal_printf(nal_cb_t *nal,
92 static void nal_cli(nal_cb_t *nal,
95 bridge b = (bridge) nal->nal_data;
96 procbridge p = (procbridge) b->local;
98 pthread_mutex_lock(&p->nal_cb_lock);
102 static void nal_sti(nal_cb_t *nal,
103 unsigned long *flags)
105 bridge b = (bridge)nal->nal_data;
106 procbridge p = (procbridge) b->local;
108 pthread_mutex_unlock(&p->nal_cb_lock);
112 static int nal_dist(nal_cb_t *nal,
119 static void wakeup_topside(void *z)
122 procbridge p = b->local;
125 pthread_mutex_lock(&p->mutex);
126 stop = p->nal_flags & NAL_FLAG_STOPPING;
128 p->nal_flags |= NAL_FLAG_STOPPED;
129 pthread_cond_broadcast(&p->cond);
130 pthread_mutex_unlock(&p->mutex);
137 /* Function: nal_thread
138 * Arguments: z: an opaque reference to a nal control structure
139 * allocated and partially populated by the api level code
140 * Returns: nothing, and only on error or explicit shutdown
142 * This function is the entry point of the pthread initiated on
143 * the api side of the interface. This thread is used to handle
144 * asynchronous delivery to the application.
146 * We define a limit macro to place a ceiling on limits
147 * for syntactic convenience
149 #define LIMIT(x,y,max)\
150 if ((unsigned int)x > max) y = max;
152 extern int tcpnal_init(bridge);
154 nal_initialize nal_table[PTL_IFACE_MAX]={0,tcpnal_init,0};
156 void *nal_thread(void *z)
158 nal_init_args_t *args = (nal_init_args_t *) z;
159 bridge b = args->nia_bridge;
160 procbridge p=b->local;
162 ptl_pid_t pid_request;
164 ptl_ni_limits_t desired;
165 ptl_ni_limits_t actual;
167 b->nal_cb=(nal_cb_t *)malloc(sizeof(nal_cb_t));
168 b->nal_cb->nal_data=b;
169 b->nal_cb->cb_read=nal_read;
170 b->nal_cb->cb_write=nal_write;
171 b->nal_cb->cb_malloc=nal_malloc;
172 b->nal_cb->cb_free=nal_free;
173 b->nal_cb->cb_map=NULL;
174 b->nal_cb->cb_unmap=NULL;
175 b->nal_cb->cb_printf=nal_printf;
176 b->nal_cb->cb_cli=nal_cli;
177 b->nal_cb->cb_sti=nal_sti;
178 b->nal_cb->cb_dist=nal_dist;
180 pid_request = args->nia_requested_pid;
181 desired = *args->nia_limits;
182 nal_type = args->nia_nal_type;
185 LIMIT(desired.max_match_entries,actual.max_match_entries,MAX_MES);
186 LIMIT(desired.max_mem_descriptors,actual.max_mem_descriptors,MAX_MDS);
187 LIMIT(desired.max_event_queues,actual.max_event_queues,MAX_EQS);
188 LIMIT(desired.max_atable_index,actual.max_atable_index,MAX_ACLS);
189 LIMIT(desired.max_ptable_index,actual.max_ptable_index,MAX_PTLS);
191 set_address(b,pid_request);
193 if (nal_table[nal_type]) rc=(*nal_table[nal_type])(b);
194 /* initialize the generic 'library' level code */
196 rc = lib_init(b->nal_cb,
200 actual.max_ptable_index,
201 actual.max_atable_index);
204 * Whatever the initialization returned is passed back to the
205 * user level code for further interpretation. We just exit if
206 * it is non-zero since something went wrong.
208 /* this should perform error checking */
209 pthread_mutex_lock(&p->mutex);
210 p->nal_flags |= rc ? NAL_FLAG_STOPPED : NAL_FLAG_RUNNING;
211 pthread_cond_broadcast(&p->cond);
212 pthread_mutex_unlock(&p->mutex);
215 /* the thunk function is called each time the timer loop
216 performs an operation and returns to blocking mode. we
217 overload this function to inform the api side that
218 it may be interested in looking at the event queue */
219 register_thunk(wakeup_topside,b);