1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (c) 2002 Cray Inc.
6 * This file is part of Portals, http://www.sf.net/projects/sandiaportals/
8 * Portals is free software; you can redistribute it and/or
9 * modify it under the terms of version 2.1 of the GNU Lesser General
10 * Public License as published by the Free Software Foundation.
12 * Portals is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with Portals; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * This file provides the 'api' side for the process-based nals.
24 * it is responsible for creating the 'library' side thread,
25 * and passing wrapped portals transactions to it.
27 * Along with initialization, shutdown, and transport to the library
28 * side, this file contains some stubs to satisfy the nal definition.
35 #include <procbridge.h>
42 * Arguments: nal_t *nal: pointer to my top-side nal structure
43 * id: the command to pass to the lower layer
44 * args, args_len:pointer to and length of the request
45 * ret, ret_len: pointer to and size of the result
46 * Returns: a portals status code
48 * forwards a packaged api call from the 'api' side to the 'library'
49 * side, and collects the result
51 #define forward_failure(operand,fd,buffer,length)\
52 if(syscall(SYS_##operand,fd,buffer,length)!=length){\
56 static int procbridge_forward(nal_t *n, int id, void *args, ptl_size_t args_len,
57 void *ret, ptl_size_t ret_len)
59 bridge b=(bridge)n->nal_data;
60 procbridge p=(procbridge)b->local;
64 forward_failure(write,lib, &id, sizeof(id));
65 forward_failure(write,lib,&args_len, sizeof(args_len));
66 forward_failure(write,lib,&ret_len, sizeof(ret_len));
67 forward_failure(write,lib,args, args_len);
70 k=syscall(SYS_read, p->from_lib[0], ret, ret_len);
71 } while ((k!=ret_len) && (errno += EINTR));
74 perror("nal: read return block");
79 #undef forward_failure
83 * Arguments: nal: a pointer to my top side nal structure
84 * ni: my network interface index
86 * cleanup nal state, reclaim the lower side thread and
87 * its state using PTL_FINI codepoint
89 static int procbridge_shutdown(nal_t *n, int ni)
91 bridge b=(bridge)n->nal_data;
92 procbridge p=(procbridge)b->local;
95 syscall(SYS_write, p->to_lib[1],&code,sizeof(code));
96 syscall(SYS_read, p->from_lib[0],&code,sizeof(code));
98 syscall(SYS_close, p->to_lib[0]);
99 syscall(SYS_close, p->to_lib[1]);
100 syscall(SYS_close, p->from_lib[0]);
101 syscall(SYS_close, p->from_lib[1]);
108 /* Function: validate
111 static int procbridge_validate(nal_t *nal, void *base, ptl_size_t extent)
120 * this function was originally intended to allow the
121 * lower half thread to be scheduled to allow progress. we
122 * overload it to explicitly block until signalled by the
125 static void procbridge_yield(nal_t *n)
127 bridge b=(bridge)n->nal_data;
128 procbridge p=(procbridge)b->local;
130 pthread_mutex_lock(&p->mutex);
131 pthread_cond_wait(&p->cond,&p->mutex);
132 pthread_mutex_unlock(&p->mutex);
136 static void procbridge_lock(nal_t * nal, unsigned long *flags){}
137 static void procbridge_unlock(nal_t * nal, unsigned long *flags){}
139 * the interface vector to allow the generic code to access
140 * this nal. this is seperate from the library side nal_cb.
141 * TODO: should be dyanmically allocated
143 static nal_t api_nal = {
146 forward: procbridge_forward,
147 shutdown: procbridge_shutdown,
148 validate: procbridge_validate,
149 yield: procbridge_yield,
150 lock: procbridge_lock,
151 unlock: procbridge_unlock
154 /* Function: bridge_init
156 * Arguments: pid: requested process id (port offset)
157 * PTL_ID_ANY not supported.
158 * desired: limits passed from the application
159 * and effectively ignored
160 * actual: limits actually allocated and returned
162 * Returns: a pointer to my statically allocated top side NAL
165 * initializes the tcp nal. we define unix_failure as an
166 * error wrapper to cut down clutter.
168 #define unix_failure(operand,fd,buffer,length,text)\
169 if(syscall(SYS_##operand,fd,buffer,length)!=length){\
174 static nal_t *bridge_init(ptl_interface_t nal,
175 ptl_pid_t pid_request,
176 ptl_ni_limits_t *desired,
177 ptl_ni_limits_t *actual,
182 static int initialized=0;
183 ptl_ni_limits_t limits = {-1,-1,-1,-1,-1};
185 if(initialized) return (&api_nal);
189 b=(bridge)malloc(sizeof(struct bridge));
190 p=(procbridge)malloc(sizeof(struct procbridge));
194 if(pipe(p->to_lib) || pipe(p->from_lib)) {
195 perror("nal_init: pipe");
199 if (desired) limits = *desired;
200 unix_failure(write,p->to_lib[1], &pid_request, sizeof(pid_request),
202 unix_failure(write,p->to_lib[1], &limits, sizeof(ptl_ni_limits_t),
204 unix_failure(write,p->to_lib[1], &nal, sizeof(ptl_interface_t),
207 if(pthread_create(&p->t, NULL, nal_thread, b)) {
208 perror("nal_init: pthread_create");
212 unix_failure(read,p->from_lib[0], actual, sizeof(ptl_ni_limits_t),
214 unix_failure(read,p->from_lib[0], rc, sizeof(rc),
217 if(*rc) return(NULL);
220 pthread_mutex_init(&p->mutex,0);
221 pthread_cond_init(&p->cond, 0);
227 ptl_nid_t tcpnal_mynid;
229 nal_t *procbridge_interface(int num_interface,
230 ptl_pt_index_t ptl_size,
231 ptl_ac_index_t acl_size,
232 ptl_pid_t requested_pid)
236 static int initialized=0;
237 ptl_ni_limits_t limits = {-1,-1,-1,-1,-1};
238 int rc, nal_type = PTL_IFACE_TCP;/* PTL_IFACE_DEFAULT FIXME hack */
240 if(initialized) return (&api_nal);
244 b=(bridge)malloc(sizeof(struct bridge));
245 p=(procbridge)malloc(sizeof(struct procbridge));
249 if(pipe(p->to_lib) || pipe(p->from_lib)) {
250 perror("nal_init: pipe");
255 limits.max_ptable_index = ptl_size;
257 limits.max_atable_index = acl_size;
259 unix_failure(write,p->to_lib[1], &requested_pid, sizeof(requested_pid),
261 unix_failure(write,p->to_lib[1], &limits, sizeof(ptl_ni_limits_t),
263 unix_failure(write,p->to_lib[1], &nal_type, sizeof(nal_type),
266 if(pthread_create(&p->t, NULL, nal_thread, b)) {
267 perror("nal_init: pthread_create");
271 unix_failure(read,p->from_lib[0], &rc, sizeof(rc),
276 b->nal_cb->ni.nid = tcpnal_mynid;
278 pthread_mutex_init(&p->mutex,0);
279 pthread_cond_init(&p->cond, 0);