sprofalyze fixes
[minix.git] / lib / libbdev / call.c
blob2a33791faf8f9cb1c48b5558a28fe24e0fd1a2dd
1 /* libbdev - asynchronous call structure management */
3 #include <minix/drivers.h>
4 #include <minix/bdev.h>
5 #include <assert.h>
7 #include "const.h"
8 #include "type.h"
9 #include "proto.h"
11 static bdev_call_t *calls[NR_CALLS];
13 bdev_call_t *bdev_call_alloc(int count)
15 /* Allocate a call structure.
17 bdev_call_t *call;
18 bdev_id_t id;
20 for (id = 0; id < NR_CALLS; id++)
21 if (calls[id] == NULL)
22 break;
24 if (id == NR_CALLS)
25 return NULL;
27 call = malloc(sizeof(bdev_call_t) +
28 sizeof(call->gvec[0]) * (count - 1) +
29 sizeof(call->vec[0]) * count);
31 if (call == NULL)
32 return NULL;
34 call->id = id;
35 call->vec = (iovec_t *) &call->gvec[count];
37 calls[id] = call;
39 return call;
42 void bdev_call_free(bdev_call_t *call)
44 /* Free a call structure.
47 assert(calls[call->id] == call);
49 calls[call->id] = NULL;
51 free(call);
54 bdev_call_t *bdev_call_get(bdev_id_t id)
56 /* Retrieve a call structure by request number.
59 if (id < 0 || id >= NR_CALLS)
60 return NULL;
62 return calls[id];
65 bdev_call_t *bdev_call_find(dev_t dev)
67 /* Find the first asynchronous request for the given device, if any.
69 bdev_id_t id;
71 for (id = 0; id < NR_CALLS; id++)
72 if (calls[id] != NULL && calls[id]->dev == dev)
73 return calls[id];
75 return NULL;
78 bdev_call_t *bdev_call_iter_maj(dev_t dev, bdev_call_t *call,
79 bdev_call_t **next)
81 /* Iterate over all asynchronous requests for a major device. This function
82 * must be safe even if the returned call structure is freed.
84 bdev_id_t id;
85 int major;
87 major = major(dev);
89 /* If this is the first invocation, find the first match. Otherwise, take the
90 * call we found to be next in the last invocation, which may be NULL.
92 if (call == NULL) {
93 for (id = 0; id < NR_CALLS; id++)
94 if (calls[id] != NULL && major(calls[id]->dev) == major)
95 break;
97 if (id == NR_CALLS)
98 return NULL;
100 call = calls[id];
101 } else {
102 if ((call = *next) == NULL)
103 return NULL;
106 /* Look for the next match, if any. */
107 *next = NULL;
109 for (id = call->id + 1; id < NR_CALLS; id++) {
110 if (calls[id] != NULL && major(calls[id]->dev) == major) {
111 *next = calls[id];
113 break;
117 return call;