question about socreate, soalloc and wait/nowait
question about socreate, soalloc and wait/nowait
- Subject: question about socreate, soalloc and wait/nowait
- From: "Peter Lovell" <email@hidden>
- Date: Tue, 12 Sep 2006 08:47:04 -0400
Hi folks,
in working through a problem, I've become quite puzzled by the wait/
nowait characteristics of soalloc and socreate. Hopefully someone can
enlighten me.
The code is in xnu-792.6.76/bsd/kern/uipc_socket.c and there are three
routines of interest:- socreate, soalloc and cached_sock_alloc. They're
all near the start of the file.
First puzzle is in socreate. At line 446 we have
so = soalloc(p != 0, dom, type);
and the first argument is whether or not it's OK to wait (i.e. block)
for the allocation. But this will always be true since p is guaranteed
to be non-NULL, having been fetched back at line 420
struct proc *p = current_proc();
The implementation of current_proc() guarantees to never return NULL.
The code, in bsd_stubs.c, looks as though it may previously have
returned NULL for kernel processes. Now, in the case where it might have
returned NULL, it instead returns "kernproc" which points to proc0
structure. This characteristic goes all the way back to OS X 10.0.
So I suspect that the socreate code was prepared to wait if current_proc
() was on behalf of a user process but not for a kernel task. This is
just speculation though -- as it is today it will always allow waiting.
The archetypical code in Stevens vol.2 does a wait-style allocation, as
does the current FreeBSD code.
The second puzzle is in the "soalloc" routine. Its signature is
struct socket *
soalloc(waitok, dom, type)
int waitok;
int dom;
int type;
There is a comment there also which says ...
* We don't implement `waitok' yet (see comments in uipc_domain.c).
but I don't see any appropriate comments in that file.
The routine does not make use of "waitok" and there's no definition for
it, such as whether it's true/false, or flags such as M_WAITOK/M_NOWAIT,
or whatever. However, soalloc does pass it on a call. The code is (in part)
if ((dom == PF_INET) && (type == SOCK_STREAM))
cached_sock_alloc(&so, waitok);
else
{
MALLOC_ZONE(so, struct socket *, sizeof(*so), socket_zone, M_WAITOK);
if (so)
bzero(so, sizeof *so);
}
So, soalloc passes waitok to cached_sock_alloc, or else does a wait-
style allocation itself.
cached_sock_alloc does appear to treat waitok as true/false -- this code
is around line 262
if (waitok)
*so = (struct socket *) zalloc(so_cache_zone);
else
*so = (struct socket *) zalloc_noblock(so_cache_zone);
However, there's one other reference to soalloc which suggests that the
sense may be different.
The implementation of sonewconn (actually done in sonewconn_internal,
look at file upic_socket2.c line 345) explicitly passes "1" as the
"waitok" argument to soalloc ...
so = soalloc(1, head->so_proto->pr_domain->dom_family, head->so_type);
This usage is quite clearly a no-wait call both in Stevens and FreeBSD
code. The original Mac OS X 10.0 release (xnu-123.5) had this argument
as "0" but it had changed to "1" by the time of Mac OS X 10.1 (xnu-201).
So, here are my questions ...
1. is there some reason for the "p != 0" usage in socreate? There are a
couple of places this occurs.
2. what is the correct definition for "waitok" in soalloc?
3. should the soaloc call in sonewconn be wait-style or nowait?
Thanks.....Peter
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden