00001
00002
00003
00004
00005 #include <types.h>
00006 #include <kern/errno.h>
00007 #include <lib.h>
00008 #include <queue.h>
00009
00010 struct queue {
00011 int size;
00012 int nextwrite;
00013 int nextread;
00014 void **data;
00015 };
00016
00017 static
00018 int
00019 q_grow(struct queue *q, int targetsize)
00020 {
00021 void **olddata = q->data;
00022 int onr = q->nextread;
00023 int onw = q->nextwrite;
00024 int osize = q->size;
00025
00026 int nsize;
00027 void **ndata;
00028
00029 int i, result;
00030
00031 nsize = q->size;
00032 while (nsize < targetsize) {
00033 nsize *= 2;
00034
00035 KASSERT(nsize > 0);
00036 }
00037 ndata = kmalloc(nsize * sizeof(void *));
00038 if (ndata == NULL) {
00039 return ENOMEM;
00040 }
00041 q->size = nsize;
00042 q->data = ndata;
00043 q->nextread = q->nextwrite = 0;
00044
00045 for (i=onr; i!=onw; i = (i+1)%osize) {
00046 result = q_addtail(q, olddata[i]);
00047 KASSERT(result==0);
00048 }
00049 kfree(olddata);
00050 return 0;
00051 }
00052
00053 struct queue *
00054 q_create(int size)
00055 {
00056 struct queue *q = kmalloc(sizeof(struct queue));
00057 if (q==NULL) {
00058 return NULL;
00059 }
00060 q->size = size;
00061 q->data = kmalloc(size * sizeof(void *));
00062 if (q->data==NULL) {
00063 kfree(q);
00064 return NULL;
00065 }
00066 q->nextread = q->nextwrite = 0;
00067 return q;
00068 }
00069
00070 int
00071 q_preallocate(struct queue *q, int size)
00072 {
00073 int result = 0;
00074
00075 KASSERT(q->size > 0);
00076
00077 if (size > q->size) {
00078 result = q_grow(q, size);
00079 }
00080 return result;
00081 }
00082
00083 inline
00084 int
00085 q_empty(struct queue *q)
00086 {
00087 return q->nextwrite == q->nextread;
00088 }
00089
00090 int
00091 q_addtail(struct queue *q, void *ptr)
00092 {
00093 int nextnext, result;
00094
00095 KASSERT(q->size > 0);
00096
00097 nextnext = (q->nextwrite+1) % q->size;
00098 if (nextnext==q->nextread) {
00099 result = q_grow(q, q->size+1);
00100 if (result) {
00101 return result;
00102 }
00103 nextnext = (q->nextwrite+1) % q->size;
00104 }
00105 q->data[q->nextwrite] = ptr;
00106 q->nextwrite = nextnext;
00107 return 0;
00108 }
00109
00110 void *
00111 q_remhead(struct queue *q)
00112 {
00113 void *ret;
00114
00115 KASSERT(q->size > 0);
00116
00117 KASSERT(!q_empty(q));
00118 ret = q->data[q->nextread];
00119 q->nextread = (q->nextread+1)%q->size;
00120 return ret;
00121 }
00122
00123 void
00124 q_destroy(struct queue *q)
00125 {
00126 KASSERT(q_empty(q));
00127 kfree(q->data);
00128 kfree(q);
00129 }
00130
00131
00132 int
00133 q_getstart(struct queue *q)
00134 {
00135 return q->nextread;
00136 }
00137
00138 int
00139 q_getend(struct queue *q)
00140 {
00141 return q->nextwrite;
00142 }
00143
00144 int
00145 q_getsize(struct queue *q)
00146 {
00147 return q->size;
00148 }
00149
00150 void *
00151 q_getguy(struct queue *q, int index)
00152 {
00153
00154
00155
00156 KASSERT(index>=0 && index<q->size);
00157 return q->data[index];
00158 }
00159
00160 void *
00161 q_peek(struct queue *q)
00162 {
00163 void *ret;
00164
00165 KASSERT(q);
00166 KASSERT(q->size > 0);
00167
00168 if (q_empty(q)) {
00169 ret = 0;
00170 } else {
00171 ret = q->data[q->nextread];
00172 }
00173 return ret;
00174 }
00175
00176 int
00177 q_len(struct queue *theq)
00178 {
00179 int count = 0;
00180 int tmp = theq->nextread;
00181 while (tmp != theq->nextwrite) {
00182 tmp = (tmp+1) % theq->size;
00183 count++;
00184 }
00185 return count;
00186 }