Main Page | Directories | File List | Globals

resources.c

Go to the documentation of this file.
00001 /*
00002  * kernel_super/resources/resources.c
00003  *
00004  * Copyright (c) 2003-2005 Lukasz Dembinski <dembol@nasa.com.pl>
00005  * All Rights Reserved
00006  * 
00007  * Date:        2005/05
00008  * Author:      Lukasz Dembinski
00009  * Info:        resources.c core file
00010  * Contact:     mailto: <dembol@nasa.com.pl>
00011  *
00012  */
00013 
00014 #include <agnix/agnix.h>
00015 #include <asm/bitops.h>
00016 #include <agnix/resources.h>
00017 #include <agnix/spinlock.h>
00018 #include <agnix/memory.h>
00019 #include <agnix/console.h>
00020 #include <asm/cpu_ops.h>
00021 
00022 #define MOD_NAME                "RES: "
00023 #define GLOBAL_RESOURCE_LEN     64
00024 #define GLOBAL_RESOURCE_DESC    0
00025 
00026 #define RESOURCES_DEBUG         0
00027 
00028 struct resource_s *resources[GLOBAL_RESOURCE_LEN];
00029 
00030 u32 global_resource_bitmap[(GLOBAL_RESOURCE_LEN << 5) + 1];
00031 
00032 struct resource_s global_resource = {
00033     .resource_name      = "global",
00034     .resource_bitmap    = global_resource_bitmap,
00035     .resource_len       = GLOBAL_RESOURCE_LEN,
00036 };
00037 
00038 int get_free_resource(int resource_desc)
00039 {
00040     struct resource_s * resource = resources[resource_desc];
00041     u32 *bitmap;
00042     int bitmap_len;
00043     int zero_bit;
00044     u32 flags;
00045 
00046     bitmap = resource->resource_bitmap;
00047     bitmap_len = resource->resource_len << 5;
00048 
00049     spin_lock_irqsave(&resource->resource_lock, flags);
00050     if ((zero_bit = find_first_zero_bit(bitmap, bitmap_len)) < bitmap_len)
00051         set_bit(zero_bit, bitmap);
00052     else
00053         zero_bit = -1;
00054         
00055     spin_unlock_irqrestore(&resource->resource_lock, flags);
00056     
00057     return zero_bit;
00058 }
00059 
00060 int put_free_resource(int resource_desc, int resource_bit)
00061 {
00062     struct resource_s * resource = resources[resource_desc];
00063     u32 *bitmap;
00064     u32  flags;
00065     int  ret = 0;
00066 
00067     if (resource == NULL) {
00068         printk(MOD_NAME "resource is NULL\n");
00069         return -1;
00070     }
00071 
00072     bitmap = resource->resource_bitmap;
00073 
00074     spin_lock_irqsave(&resource->resource_lock, flags);
00075     if (!test_and_clear_bit(resource_bit, bitmap)) {
00076         printk(MOD_NAME "there is zero bit on %d position in a queue_bitmap", resource_bit);
00077         ret = -1;
00078     }
00079     spin_unlock_irqrestore(&resource->resource_lock, flags);
00080 
00081     return ret;
00082 }
00083 
00084 int request_resource(int resource_desc, int resource_bit)
00085 {
00086     struct resource_s * resource = resources[resource_desc];
00087     u32 *bitmap;
00088     int bitmap_len;
00089     int ret;
00090     u32 flags;
00091 
00092     if (resource == NULL) {
00093         printk(MOD_NAME "resource is NULL\n");
00094         return -1;
00095     }
00096 
00097     bitmap = resource->resource_bitmap;
00098     bitmap_len = resource->resource_len << 5;
00099 
00100     spin_lock_irqsave(&resource->resource_lock, flags);
00101     if (!test_and_set_bit(resource_bit, bitmap))
00102     {
00103         printk(MOD_NAME "%s requesting %d resource\n", resource->resource_name, resource_bit);
00104         ret = 0;
00105     } else {
00106         printk(MOD_NAME "%s resource %d is busy\n", resource->resource_name, resource_bit);
00107         ret = -1;
00108     }
00109     
00110     spin_unlock_irqrestore(&resource->resource_lock, flags);
00111     
00112     return ret;
00113 }
00114 
00115 int register_resource(struct resource_s *resource)
00116 {
00117     int resource_desc;
00118 
00119 #if RESOURCES_DEBUG
00120     printk(MOD_NAME "Registering %s resource\n", resource->resource_name);
00121 #endif
00122     
00123     resource_desc = get_free_resource(GLOBAL_RESOURCE_DESC);
00124     resources[resource_desc] = resource;    
00125     memset(resource->resource_bitmap, 0, resource->resource_len);
00126 
00127     return resource_desc;
00128 }
00129 
00130 void unregister_resource(int resource_desc)
00131 {
00132 }
00133 
00134 int resources_init(void)
00135 {
00136     int i;
00137 
00138     printk(MOD_NAME "Initializing %s resource\n", global_resource.resource_name);
00139     
00140     spin_lock_init(&global_resource.resource_lock);    
00141     
00142     /* sanity loop */
00143     for (i = 0; i < GLOBAL_RESOURCE_LEN; i++) {
00144         resources[i] = NULL;
00145     }
00146     resources[GLOBAL_RESOURCE_DESC] = &global_resource;
00147     set_bit(GLOBAL_RESOURCE_DESC, global_resource_bitmap);
00148     
00149     return 0;
00150 }
Dokumentacje wygenerowano programem Doxygen 1.4.2 dla projektu Agnix