00001
00002
00003
00004
00005
00006 #include <linux/config.h>
00007 #include <linux/compiler.h>
00008 #include <linux/init.h>
00009 #include <linux/mm.h>
00010
00011 #include<irpdef.h>
00012 #include<npool_data.h>
00013 #include<ssdef.h>
00014 #include<system_data_cells.h>
00015 #include <exe_routines.h>
00016 #include <misc_routines.h>
00017 #include <mmg_routines.h>
00018 #include <internals.h>
00019 #include <ipldef.h>
00020
00021 struct _myhead {
00022 struct _myhead * hd_l_flink;
00023 long hd_l_seq;
00024 };
00025
00026 void exe_reclaim_pool_aggressive(void * pool);
00027
00028
00029 int exe_allocate_pool(int requestsize, int pooltype, int alignment, unsigned int * allocatedsize, void ** returnblock) {
00030 int reqsize=requestsize;
00031 unsigned int * alosize_p=allocatedsize;
00032 void ** pool_p=returnblock;
00033 int sts=SS__NORMAL;
00034
00035
00036 if (reqsize&63)
00037 reqsize=((reqsize>>6)+1)<<6;
00038
00039 *alosize_p=reqsize;
00040
00041 struct _npool_data * pooldata = exe_gs_bap_npool;
00042 struct _lsthds * lsthd = pooldata->npool_ar_lsthds;
00043 struct _myhead * array = &lsthd->lsthds_q_listheads;
00044
00045 if (reqsize<=8192) {
00046 *pool_p = exe_lal_remove_first(&array[reqsize>>6]);
00047 if (*pool_p) {
00048 check_packet(*pool_p,reqsize,0);
00049 #if 0
00050 poison_packet(*pool_p,reqsize,0);
00051 #endif
00052 }
00053 }
00054
00055
00056 if (*pool_p)
00057 return sts;
00058
00059 int ipl = vmslock(&SPIN_POOL, IPL__POOL);
00060 sts=exe_allocate(reqsize , &exe$gq_bap_variable, 0 , alosize_p, pool_p);
00061 vmsunlock(&SPIN_POOL, ipl);
00062
00063
00064
00065 if (sts==SS__NORMAL)
00066 return sts;
00067
00068 #if 0
00069 struct _npool_data * pooldata = exe_gs_bap_npool;
00070 struct _lsthds * lsthd = pooldata->npool_ar_lsthds;
00071 void * array = &lsthd->lsthds_q_listheads;
00072 #endif
00073
00074 exe_reclaim_pool_aggressive(exe$gs_bap_npool);
00075 ipl = vmslock(&SPIN_POOL, IPL__POOL);
00076 sts=exe_allocate(reqsize , &exe$gq_bap_variable, 0 , alosize_p, pool_p);
00077 vmsunlock(&SPIN_POOL, ipl);
00078
00079 if (sts==SS__NORMAL)
00080 return sts;
00081
00082 sts=exe_extendpool(exe$gs_bap_npool);
00083 if (sts==SS__NORMAL) {
00084 int ipl = vmslock(&SPIN_POOL, IPL__POOL);
00085 sts=exe_allocate(reqsize , &exe$gq_bap_variable, 0 , alosize_p, pool_p);
00086 vmsunlock(&SPIN_POOL, ipl);
00087 }
00088
00089 if (sts==SS__NORMAL)
00090 return sts;
00091
00092 sts=exe_flushlists(exe$gs_bap_npool, reqsize);
00093
00094 if (sts==SS__NORMAL) {
00095 int ipl = vmslock(&SPIN_POOL, IPL__POOL);
00096 sts=exe_allocate(reqsize , &exe$gq_bap_variable, 0 , alosize_p, pool_p);
00097 vmsunlock(&SPIN_POOL, ipl);
00098 }
00099
00100 return sts;
00101 }
00102
00103 void exe_deallocate_pool(void * returnblock, int pooltype, int size) {
00104 void * pool=returnblock;
00105 if (size&63)
00106 size=((size>>6)+1)<<6;
00107
00108 if (size==0 || (size&63))
00109 panic("size size %x\n",size);
00110
00111 struct _npool_data * pooldata = exe_gs_bap_npool;
00112 struct _lsthds * lsthd = pooldata->npool_ar_lsthds;
00113 struct _myhead * array = &lsthd->lsthds_q_listheads;
00114
00115 if (size<=8192) {
00116 poison_packet(pool,size,1);
00117 exe_lal_insert_first(pool, &array[size>>6]);
00118 } else {
00119 int ipl = vmslock(&SPIN_POOL, IPL__POOL);
00120 int sts=exe_deallocate(pool, exe$gq_bap_variable, size);
00121 vmsunlock(&SPIN_POOL, ipl);
00122 }
00123 return SS__NORMAL;
00124 }
00125
00126 exe_extend_npp(void * pool) {
00127
00128 printk("exe_extendpool/npp not yet implemented (not so difficult?\n");
00129 return SS__INSFMEM;
00130 }
00131
00132 exe_extendpool(void * pool) {
00133 return exe_extend_npp(pool);
00134 }
00135
00136 static int trim=1;
00137
00138 exe_trim_pool_list(int percentage, void * listhead, void * basepool) {
00139
00140 struct _myhead * hd = listhead;
00141 int cut;
00142 cut = hd[trim].hd_l_seq * percentage / 100;
00143 for (; cut; cut--) {
00144 void * ret = exe_lal_remove_first(&hd[trim]);
00145 if (ret) {
00146 int ipl = vmslock(&SPIN_POOL, IPL__POOL);
00147 exe_deallocate(ret, basepool, 64*trim);
00148 vmsunlock(&SPIN_POOL, ipl);
00149 }
00150 }
00151 cut = hd[64+trim].hd_l_seq * (100 - percentage) / 100;
00152 for (; cut; cut--) {
00153 void * ret = exe_lal_remove_first(&hd[64+trim]);
00154 if (ret) {
00155 int ipl = vmslock(&SPIN_POOL, IPL__POOL);
00156 exe_deallocate(ret, basepool, 64*(64+trim));
00157 vmsunlock(&SPIN_POOL, ipl);
00158 }
00159 }
00160 trim++;
00161 if (trim>64)
00162 trim=1;
00163 }
00164
00165 void exe_reclaim_pool_aggressive(void * pool) {
00166 struct _npool_data * pooldata = pool;
00167 struct _lsthds * lsthd = pooldata->npool_ar_lsthds;
00168 void * array = &lsthd->lsthds_q_listheads;
00169 void * listhead=array;
00170 void * basepool=lsthd->lsthds_l_variablelist_unused;
00171 exe_trim_pool_list(50,listhead, basepool);
00172 }
00173
00174 void exe_reclaim_pool_gentle(void * pool) {
00175 printk("timer exe_reclaim_pool_gentle %x\n",trim);
00176 struct _npool_data * pooldata = pool;
00177 struct _lsthds * lsthd = pooldata->npool_ar_lsthds;
00178 void * array = &lsthd->lsthds_q_listheads;
00179 void * listhead=array;
00180 void * basepool=lsthd->lsthds_l_variablelist_unused;
00181 exe_trim_pool_list(85,listhead, basepool);
00182 signed long long time=-10000000*60;
00183 exe_setimr(0, &time, exe$reclaim_pool_gentle, exe$gs_npp_npool, 0);
00184 }
00185
00186