Main Page | Directories | File List | Globals

queues.c

Go to the documentation of this file.
00001 /*
00002  * kernel_libs/queues/queues.c
00003  *
00004  * Copyright (c) 2003-2004 Lukasz Dembinski <dembol@nasa.com.pl>
00005  * All Rights Reserved
00006  * 
00007  * Date:        2004/05
00008  * Author:      Lukasz Dembinski
00009  * Info:        queues.c core file
00010  * Contact:     mailto: <dembol@nasa.com.pl>
00011  *
00012  */
00013 
00014 #include <agnix/agnix.h>
00015 #include <agnix/memory.h>
00016 #include <agnix/queues.h>
00017 #include <agnix/spinlock.h>
00018 #include <agnix/resources.h>
00019 #include <agnix/console.h>
00020 #include <asm/cpu_ops.h>
00021 
00022 #define QUEUES_DEBUG    0
00023 #define MOD_NAME        "QUEUES: "
00024 
00025 struct queue_type_s *queue_types[MAX_QUEUE_TYPES];
00026 struct queue_s      queues[MAX_QUEUES];
00027 
00028 u32    queue_bitmap[QUEUE_BITMAP_LEN];
00029 
00030 int queues_resource_desc;
00031 struct resource_s queues_resource = {
00032     .resource_name      = "queues",
00033     .resource_bitmap    = queue_bitmap,
00034     .resource_len       = QUEUE_BITMAP_LEN,
00035 };
00036 
00037 int queue_enqueue(int queue_desc, struct queue_entry_s *queue_entry)
00038 {
00039     struct queue_s *queue = &queues[queue_desc];
00040     u32 flags;
00041 
00042     spin_lock_irqsave(&queue->queue_lock, flags);
00043     queue->queue_ops->enqueue(queue, queue_entry);
00044     spin_unlock_irqrestore(&queue->queue_lock, flags);
00045 
00046     return 0;
00047 }
00048 
00049 struct queue_entry_s *queue_dequeue(int queue_desc)
00050 {
00051     struct queue_entry_s *queue_entry;
00052     struct queue_s *queue = &queues[queue_desc];
00053     u32 flags;
00054 
00055     spin_lock_irqsave(&queue->queue_lock, flags);
00056     queue_entry = queue->queue_ops->dequeue(queue);
00057     spin_unlock_irqrestore(&queue->queue_lock, flags);
00058 
00059     return queue_entry;
00060 }
00061 
00062 int queue_empty(int queue_desc)
00063 {
00064     struct queue_s *queue = &queues[queue_desc];
00065     int empty;
00066     u32 flags;
00067 
00068     spin_lock_irqsave(&queue->queue_lock, flags);
00069     empty = list_empty(&queue->queue_list);
00070     spin_unlock_irqrestore(&queue->queue_lock, flags);
00071     
00072     return empty;
00073 }
00074 
00075 void queue_free(int queue_desc)
00076 {
00077     struct queue_s *queue = &queues[queue_desc];
00078     u32 flags;
00079 
00080     spin_lock_irqsave(&queue->queue_lock, flags);
00081     INIT_LIST_HEAD(&queue->queue_list);
00082     spin_unlock_irqrestore(&queue->queue_lock, flags);
00083 }
00084 
00085 int put_free_queue(int queue_desc)
00086 {
00087     return put_free_resource(queues_resource_desc, queue_desc);
00088 }
00089 
00090 int get_free_queue(void)
00091 {
00092     return get_free_resource(queues_resource_desc);
00093 }
00094 
00095 int register_queue(int queue_type, const char *queue_name)
00096 {
00097     struct queue_s *queue;
00098     int queue_desc = 0;
00099     
00100     if (queue_types[queue_type] == NULL) {
00101         printk(MOD_NAME "queue type %d not registered...\n", queue_type);
00102         return -1;
00103     }
00104     
00105     if ((queue_desc = get_free_queue()) < 0) {
00106         printk(MOD_NAME "can not register %s queue, type %d\n", queue_name, queue_type);
00107         return -1;
00108     }
00109 #if QUEUES_DEBUG
00110     else
00111         printk(MOD_NAME "registering %s queue, type %s\n", queue_name, queue_types[queue_type]->queue_type_name);
00112 #endif
00113 
00114     queue = &queues[queue_type];
00115     queue->queue_name = queue_name;
00116     queue->queue_type = queue_type;
00117     queue->queue_ops  = queue_types[queue_type]->queue_type_ops->queue_ops;
00118     INIT_LIST_HEAD(&queue->queue_list);
00119 
00120     if (queue->queue_ops && queue->queue_ops->init)
00121         queue->queue_ops->init(queue);
00122 
00123     atomic_inc(&queue_types[queue_type]->queue_type_count);
00124 
00125     return queue_desc;
00126 }
00127 
00128 int unregister_queue(int queue_desc)
00129 {
00130     struct queue_s *queue;
00131     const char *queue_name;
00132     int queue_type;
00133     int ret;
00134 
00135     queue = &queues[queue_desc];
00136 
00137     queue_name = queue->queue_name;
00138     queue_type = queue->queue_type;
00139 
00140     if ((ret = put_free_queue(queue_desc)) < 0) {
00141         printk(MOD_NAME "can not unregister %s queue, type %d\n", queue_name, queue_type);
00142         return -1;
00143     }
00144 #if QUEUES_DEBUG
00145     else
00146         printk(MOD_NAME "unregistering %s queue, type %s\n", queue_name, queue_types[queue_type]->queue_type_name);
00147 #endif
00148 
00149     if (queue->queue_ops && queue->queue_ops->remove)
00150         queue->queue_ops->remove(queue);
00151 
00152     atomic_dec(&queue_types[queue_type]->queue_type_count);
00153 
00154     return 0;
00155 }
00156 
00157 int register_queue_type(struct queue_type_s *queue)
00158 {
00159     struct queue_type_ops_s *queue_type_ops;
00160     int queue_type;
00161     int ret = 0;
00162 
00163     if (queue == NULL) {
00164         printk(MOD_NAME "can not register queue_type with NULL pointer...\n");
00165         return -1;
00166     }
00167 
00168     queue_type = queue->queue_type;
00169 
00170     if (queue_types[queue_type]) {
00171         printk(MOD_NAME "queue_type %d already registered...\n", queue_type);
00172         return -1;
00173     }
00174 #if QUEUES_DEBUG
00175     else
00176         printk(MOD_NAME "registering %s queue type (%d)\n", queue->queue_type_name, queue_type);
00177 #endif
00178 
00179     queue_types[queue_type] = queue;
00180     queue_type_ops = queue->queue_type_ops;
00181 
00182     if (queue_type_ops && queue_type_ops->init) {
00183         ret = queue_type_ops->init(queue);
00184     }
00185 
00186     return ret;
00187 }
00188 
00189 int unregister_queue_type(int queue_type)
00190 {
00191     struct queue_type_s *queue;
00192     struct queue_type_ops_s *queue_type_ops;
00193     int ret = 0;
00194 
00195     queue = queue_types[queue_type];
00196 
00197     if (queue == NULL) {
00198         printk(MOD_NAME "queue type %d not registered...\n", queue_type);
00199         return -1;
00200     }
00201 
00202     if (atomic_read(&queue->queue_type_count) == 0) {
00203 
00204 #if QUEUES_DEBUG
00205         printk(MOD_NAME "unregistering %s queue type (%d)\n", queue->queue_type_name, queue_type);
00206 #endif
00207         queue_type_ops = queue->queue_type_ops;
00208         if (queue_type_ops && queue_type_ops->remove) {
00209             ret = queue_type_ops->remove(queue);
00210         }
00211     } else {
00212         printk(MOD_NAME "queue type %d already in use...\n", queue_type);
00213         ret = -1;
00214     }
00215 
00216     return ret;
00217 }
00218 
00219 int queues_init(void)
00220 {
00221     int i;
00222 
00223     printk(MOD_NAME "initializing queues\n");
00224 
00225     queues_resource_desc = register_resource(&queues_resource);
00226     memset(queue_types, 0, MAX_QUEUE_TYPES * sizeof(struct queue_type_s));
00227 
00228     for (i = 0; i < MAX_QUEUES; i++) {
00229         INIT_LIST_HEAD(&queues[i].queue_list);
00230         spin_lock_init(&queues[i].queue_lock);
00231     }
00232 
00233     queues_fifo_init();
00234     queues_lifo_init();
00235 
00236     return 0;
00237 }
Dokumentacje wygenerowano programem Doxygen 1.4.2 dla projektu Agnix