1*fcf3ce44SJohn Forte /* 2*fcf3ce44SJohn Forte * CDDL HEADER START 3*fcf3ce44SJohn Forte * 4*fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the 5*fcf3ce44SJohn Forte * Common Development and Distribution License (the "License"). 6*fcf3ce44SJohn Forte * You may not use this file except in compliance with the License. 7*fcf3ce44SJohn Forte * 8*fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing. 10*fcf3ce44SJohn Forte * See the License for the specific language governing permissions 11*fcf3ce44SJohn Forte * and limitations under the License. 12*fcf3ce44SJohn Forte * 13*fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each 14*fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the 16*fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying 17*fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner] 18*fcf3ce44SJohn Forte * 19*fcf3ce44SJohn Forte * CDDL HEADER END 20*fcf3ce44SJohn Forte */ 21*fcf3ce44SJohn Forte 22*fcf3ce44SJohn Forte /* 23*fcf3ce44SJohn Forte * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24*fcf3ce44SJohn Forte * Use is subject to license terms. 25*fcf3ce44SJohn Forte */ 26*fcf3ce44SJohn Forte 27*fcf3ce44SJohn Forte #include <stdio.h> 28*fcf3ce44SJohn Forte #include <stdlib.h> 29*fcf3ce44SJohn Forte #include <string.h> 30*fcf3ce44SJohn Forte #include <unistd.h> 31*fcf3ce44SJohn Forte #include <pthread.h> 32*fcf3ce44SJohn Forte 33*fcf3ce44SJohn Forte #include "isns_server.h" 34*fcf3ce44SJohn Forte #include "isns_protocol.h" 35*fcf3ce44SJohn Forte #include "isns_log.h" 36*fcf3ce44SJohn Forte #include "isns_sched.h" 37*fcf3ce44SJohn Forte #include "isns_scn.h" 38*fcf3ce44SJohn Forte #include "isns_esi.h" 39*fcf3ce44SJohn Forte 40*fcf3ce44SJohn Forte /* 41*fcf3ce44SJohn Forte * extern variables. 42*fcf3ce44SJohn Forte */ 43*fcf3ce44SJohn Forte 44*fcf3ce44SJohn Forte /* 45*fcf3ce44SJohn Forte * global variables. 46*fcf3ce44SJohn Forte */ 47*fcf3ce44SJohn Forte pthread_mutex_t el_mtx = PTHREAD_MUTEX_INITIALIZER; 48*fcf3ce44SJohn Forte 49*fcf3ce44SJohn Forte /* 50*fcf3ce44SJohn Forte * local variables. 51*fcf3ce44SJohn Forte */ 52*fcf3ce44SJohn Forte static el_key_t **il; 53*fcf3ce44SJohn Forte static int icurr = 0; 54*fcf3ce44SJohn Forte static el_notice_t *curr = NULL; 55*fcf3ce44SJohn Forte 56*fcf3ce44SJohn Forte static uint32_t DU; 57*fcf3ce44SJohn Forte static uint32_t DT; 58*fcf3ce44SJohn Forte static uint32_t LB; 59*fcf3ce44SJohn Forte static uint32_t NLIM; 60*fcf3ce44SJohn Forte 61*fcf3ce44SJohn Forte /* 62*fcf3ce44SJohn Forte * external variables. 63*fcf3ce44SJohn Forte */ 64*fcf3ce44SJohn Forte 65*fcf3ce44SJohn Forte /* 66*fcf3ce44SJohn Forte * local functions. 67*fcf3ce44SJohn Forte */ 68*fcf3ce44SJohn Forte 69*fcf3ce44SJohn Forte /* 70*fcf3ce44SJohn Forte * **************************************************************************** 71*fcf3ce44SJohn Forte * 72*fcf3ce44SJohn Forte * il_shift: 73*fcf3ce44SJohn Forte * Shift the indexed-list to the most current time. 74*fcf3ce44SJohn Forte * 75*fcf3ce44SJohn Forte * t - most current time. 76*fcf3ce44SJohn Forte * 77*fcf3ce44SJohn Forte * **************************************************************************** 78*fcf3ce44SJohn Forte */ 79*fcf3ce44SJohn Forte static void 80*fcf3ce44SJohn Forte il_shift( 81*fcf3ce44SJohn Forte uint32_t t 82*fcf3ce44SJohn Forte ) 83*fcf3ce44SJohn Forte { 84*fcf3ce44SJohn Forte el_notice_t *fn, *n; 85*fcf3ce44SJohn Forte el_key_t *fk, *k; 86*fcf3ce44SJohn Forte uint32_t nt; 87*fcf3ce44SJohn Forte int c; 88*fcf3ce44SJohn Forte 89*fcf3ce44SJohn Forte k = il[icurr]; 90*fcf3ce44SJohn Forte while (k->time < t) { 91*fcf3ce44SJohn Forte fk = k; 92*fcf3ce44SJohn Forte fn = k->notice; 93*fcf3ce44SJohn Forte /* remove the dummy key and dummy notice */ 94*fcf3ce44SJohn Forte fk->left->right = fk->right; 95*fcf3ce44SJohn Forte fk->right->left = fk->left; 96*fcf3ce44SJohn Forte fn->pred->sucd = fn->sucd; 97*fcf3ce44SJohn Forte fn->sucd->pred = fn->pred; 98*fcf3ce44SJohn Forte 99*fcf3ce44SJohn Forte /* find the place where the dummy goes to */ 100*fcf3ce44SJohn Forte k = il[(icurr + DU - 1) % DU]; 101*fcf3ce44SJohn Forte if (k->time < INFINITY - DT) { 102*fcf3ce44SJohn Forte nt = k->time + DT; /* next key time */ 103*fcf3ce44SJohn Forte } else { 104*fcf3ce44SJohn Forte nt = INFINITY - 1; /* the last second */ 105*fcf3ce44SJohn Forte } 106*fcf3ce44SJohn Forte while (k->time < nt) { 107*fcf3ce44SJohn Forte k = k->right; 108*fcf3ce44SJohn Forte } 109*fcf3ce44SJohn Forte n = k->notice->pred; 110*fcf3ce44SJohn Forte c = 1; 111*fcf3ce44SJohn Forte while (n->time >= nt) { 112*fcf3ce44SJohn Forte c ++; 113*fcf3ce44SJohn Forte n = n->pred; 114*fcf3ce44SJohn Forte } 115*fcf3ce44SJohn Forte n = n->sucd; 116*fcf3ce44SJohn Forte 117*fcf3ce44SJohn Forte /* update lower bound */ 118*fcf3ce44SJohn Forte LB = fk->time; 119*fcf3ce44SJohn Forte 120*fcf3ce44SJohn Forte /* insert the dummy key */ 121*fcf3ce44SJohn Forte fk->time = nt; 122*fcf3ce44SJohn Forte fk->count = k->count - c + 1; 123*fcf3ce44SJohn Forte fk->left = k->left; 124*fcf3ce44SJohn Forte fk->right = k; 125*fcf3ce44SJohn Forte k->left->right = fk; 126*fcf3ce44SJohn Forte k->left = fk; 127*fcf3ce44SJohn Forte k->count = c; 128*fcf3ce44SJohn Forte /* insert the dummy notice */ 129*fcf3ce44SJohn Forte fn->time = nt; 130*fcf3ce44SJohn Forte fn->pred = n->pred; 131*fcf3ce44SJohn Forte fn->sucd = n; 132*fcf3ce44SJohn Forte n->pred->sucd = fn; 133*fcf3ce44SJohn Forte n->pred = fn; 134*fcf3ce44SJohn Forte 135*fcf3ce44SJohn Forte /* shift the current index */ 136*fcf3ce44SJohn Forte icurr = (icurr + 1) % DU; 137*fcf3ce44SJohn Forte k = il[icurr]; 138*fcf3ce44SJohn Forte } 139*fcf3ce44SJohn Forte } 140*fcf3ce44SJohn Forte 141*fcf3ce44SJohn Forte /* 142*fcf3ce44SJohn Forte * global functions. 143*fcf3ce44SJohn Forte */ 144*fcf3ce44SJohn Forte 145*fcf3ce44SJohn Forte /* 146*fcf3ce44SJohn Forte * **************************************************************************** 147*fcf3ce44SJohn Forte * 148*fcf3ce44SJohn Forte * el_init: 149*fcf3ce44SJohn Forte * Initialize the element list. 150*fcf3ce44SJohn Forte * 151*fcf3ce44SJohn Forte * du - Number of uint in the indexed-list. 152*fcf3ce44SJohn Forte * dt - Time interval of the indexed-list. 153*fcf3ce44SJohn Forte * nlim - Limit number of each notice. 154*fcf3ce44SJohn Forte * return - 0: successful, otherwise failed. 155*fcf3ce44SJohn Forte * 156*fcf3ce44SJohn Forte * **************************************************************************** 157*fcf3ce44SJohn Forte */ 158*fcf3ce44SJohn Forte int 159*fcf3ce44SJohn Forte el_init( 160*fcf3ce44SJohn Forte uint32_t du, 161*fcf3ce44SJohn Forte uint32_t dt, 162*fcf3ce44SJohn Forte uint32_t nlim 163*fcf3ce44SJohn Forte ) 164*fcf3ce44SJohn Forte { 165*fcf3ce44SJohn Forte el_key_t *k, *kleft; 166*fcf3ce44SJohn Forte el_notice_t *n, *npred; 167*fcf3ce44SJohn Forte 168*fcf3ce44SJohn Forte uint32_t t = 0; 169*fcf3ce44SJohn Forte 170*fcf3ce44SJohn Forte int i; 171*fcf3ce44SJohn Forte 172*fcf3ce44SJohn Forte if (du < 1 || dt < 1 || nlim < 1) { 173*fcf3ce44SJohn Forte return (1); 174*fcf3ce44SJohn Forte } 175*fcf3ce44SJohn Forte 176*fcf3ce44SJohn Forte DU = du; 177*fcf3ce44SJohn Forte DT = dt; 178*fcf3ce44SJohn Forte LB = 0; 179*fcf3ce44SJohn Forte NLIM = nlim; 180*fcf3ce44SJohn Forte 181*fcf3ce44SJohn Forte /* 182*fcf3ce44SJohn Forte * initialize the event set 183*fcf3ce44SJohn Forte */ 184*fcf3ce44SJohn Forte 185*fcf3ce44SJohn Forte /* first dummy notice */ 186*fcf3ce44SJohn Forte n = (el_notice_t *)malloc(sizeof (el_notice_t)); 187*fcf3ce44SJohn Forte if (n == NULL) { 188*fcf3ce44SJohn Forte return (1); 189*fcf3ce44SJohn Forte } 190*fcf3ce44SJohn Forte n->time = LB; 191*fcf3ce44SJohn Forte n->event = NULL; 192*fcf3ce44SJohn Forte n->isdummy = 1; 193*fcf3ce44SJohn Forte n->pred = NULL; 194*fcf3ce44SJohn Forte npred = n; 195*fcf3ce44SJohn Forte 196*fcf3ce44SJohn Forte /* first dummy key */ 197*fcf3ce44SJohn Forte k = (el_key_t *)malloc(sizeof (el_key_t)); 198*fcf3ce44SJohn Forte if (k == NULL) { 199*fcf3ce44SJohn Forte return (1); 200*fcf3ce44SJohn Forte } 201*fcf3ce44SJohn Forte k->time = LB; 202*fcf3ce44SJohn Forte k->count = 1; 203*fcf3ce44SJohn Forte k->notice = n; 204*fcf3ce44SJohn Forte k->left = NULL; 205*fcf3ce44SJohn Forte kleft = k; 206*fcf3ce44SJohn Forte 207*fcf3ce44SJohn Forte n->key = k; 208*fcf3ce44SJohn Forte 209*fcf3ce44SJohn Forte /* index list */ 210*fcf3ce44SJohn Forte il = (el_key_t **)malloc((DU + 1) * sizeof (el_key_t *)); 211*fcf3ce44SJohn Forte if (il == NULL) { 212*fcf3ce44SJohn Forte return (1); 213*fcf3ce44SJohn Forte } 214*fcf3ce44SJohn Forte 215*fcf3ce44SJohn Forte /* create notice list, key list & index list */ 216*fcf3ce44SJohn Forte for (i = 0; i < DU; i++) { 217*fcf3ce44SJohn Forte t += DT; 218*fcf3ce44SJohn Forte 219*fcf3ce44SJohn Forte n = (el_notice_t *)malloc(sizeof (el_notice_t)); 220*fcf3ce44SJohn Forte if (n == NULL) { 221*fcf3ce44SJohn Forte return (1); 222*fcf3ce44SJohn Forte } 223*fcf3ce44SJohn Forte n->time = t; 224*fcf3ce44SJohn Forte n->event = NULL; 225*fcf3ce44SJohn Forte n->isdummy = 1; 226*fcf3ce44SJohn Forte n->pred = npred; 227*fcf3ce44SJohn Forte npred->sucd = n; 228*fcf3ce44SJohn Forte npred = n; 229*fcf3ce44SJohn Forte 230*fcf3ce44SJohn Forte k = (el_key_t *)malloc(sizeof (el_key_t)); 231*fcf3ce44SJohn Forte if (k == NULL) { 232*fcf3ce44SJohn Forte return (1); 233*fcf3ce44SJohn Forte } 234*fcf3ce44SJohn Forte k->time = t; 235*fcf3ce44SJohn Forte k->count = 1; 236*fcf3ce44SJohn Forte k->notice = n; 237*fcf3ce44SJohn Forte k->left = kleft; 238*fcf3ce44SJohn Forte kleft->right = k; 239*fcf3ce44SJohn Forte kleft = k; 240*fcf3ce44SJohn Forte 241*fcf3ce44SJohn Forte n->key = k; 242*fcf3ce44SJohn Forte 243*fcf3ce44SJohn Forte il[i] = k; 244*fcf3ce44SJohn Forte } 245*fcf3ce44SJohn Forte 246*fcf3ce44SJohn Forte /* last dummy notice */ 247*fcf3ce44SJohn Forte n = (el_notice_t *)malloc(sizeof (el_notice_t)); 248*fcf3ce44SJohn Forte if (n == NULL) { 249*fcf3ce44SJohn Forte return (1); 250*fcf3ce44SJohn Forte } 251*fcf3ce44SJohn Forte n->time = INFINITY; /* the end of the world */ 252*fcf3ce44SJohn Forte n->event = NULL; 253*fcf3ce44SJohn Forte n->isdummy = 1; 254*fcf3ce44SJohn Forte n->pred = npred; 255*fcf3ce44SJohn Forte n->sucd = NULL; 256*fcf3ce44SJohn Forte npred->sucd = n; 257*fcf3ce44SJohn Forte 258*fcf3ce44SJohn Forte /* last dummy key */ 259*fcf3ce44SJohn Forte k = (el_key_t *)malloc(sizeof (el_key_t)); 260*fcf3ce44SJohn Forte if (k == NULL) { 261*fcf3ce44SJohn Forte return (1); 262*fcf3ce44SJohn Forte } 263*fcf3ce44SJohn Forte k->time = INFINITY; /* the end of the world */ 264*fcf3ce44SJohn Forte k->count = 1; 265*fcf3ce44SJohn Forte k->notice = n; 266*fcf3ce44SJohn Forte k->left = kleft; 267*fcf3ce44SJohn Forte k->right = NULL; 268*fcf3ce44SJohn Forte kleft->right = k; 269*fcf3ce44SJohn Forte 270*fcf3ce44SJohn Forte n->key = k; 271*fcf3ce44SJohn Forte 272*fcf3ce44SJohn Forte /* last index */ 273*fcf3ce44SJohn Forte il[DU] = k; 274*fcf3ce44SJohn Forte 275*fcf3ce44SJohn Forte return (0); 276*fcf3ce44SJohn Forte } 277*fcf3ce44SJohn Forte 278*fcf3ce44SJohn Forte /* 279*fcf3ce44SJohn Forte * **************************************************************************** 280*fcf3ce44SJohn Forte * 281*fcf3ce44SJohn Forte * el_add: 282*fcf3ce44SJohn Forte * Add an event to the element list with it's execution time. 283*fcf3ce44SJohn Forte * It might not actually put the event to the list if the event 284*fcf3ce44SJohn Forte * is the most current one for execution. 285*fcf3ce44SJohn Forte * 286*fcf3ce44SJohn Forte * ev - The Event. 287*fcf3ce44SJohn Forte * t - The time when the event is scheduled at. 288*fcf3ce44SJohn Forte * evp - Pointer of event for returning. 289*fcf3ce44SJohn Forte * return - Error code. 290*fcf3ce44SJohn Forte * 291*fcf3ce44SJohn Forte * **************************************************************************** 292*fcf3ce44SJohn Forte */ 293*fcf3ce44SJohn Forte int 294*fcf3ce44SJohn Forte el_add( 295*fcf3ce44SJohn Forte void *ev, 296*fcf3ce44SJohn Forte uint32_t t, 297*fcf3ce44SJohn Forte void **evp 298*fcf3ce44SJohn Forte ) 299*fcf3ce44SJohn Forte { 300*fcf3ce44SJohn Forte int ec = 0; 301*fcf3ce44SJohn Forte 302*fcf3ce44SJohn Forte uint32_t t1 = 0; 303*fcf3ce44SJohn Forte 304*fcf3ce44SJohn Forte int i, j; 305*fcf3ce44SJohn Forte el_key_t *k; 306*fcf3ce44SJohn Forte el_notice_t *n; 307*fcf3ce44SJohn Forte 308*fcf3ce44SJohn Forte el_key_t *y; 309*fcf3ce44SJohn Forte el_notice_t *x; 310*fcf3ce44SJohn Forte 311*fcf3ce44SJohn Forte /* lock the event set */ 312*fcf3ce44SJohn Forte (void) pthread_mutex_lock(&el_mtx); 313*fcf3ce44SJohn Forte 314*fcf3ce44SJohn Forte /* strip it off from the event list which is being handled */ 315*fcf3ce44SJohn Forte if (evf_again(ev) != 0) { 316*fcf3ce44SJohn Forte /* if it is rescheduling an event and the event */ 317*fcf3ce44SJohn Forte /* was waiting for execution after idle finishes */ 318*fcf3ce44SJohn Forte if (evf_rem(ev) == 0 && 319*fcf3ce44SJohn Forte evp != NULL && 320*fcf3ce44SJohn Forte (curr == NULL || t <= curr->time)) { 321*fcf3ce44SJohn Forte /* no need to reschedule it */ 322*fcf3ce44SJohn Forte *evp = ev; 323*fcf3ce44SJohn Forte goto add_done; 324*fcf3ce44SJohn Forte } 325*fcf3ce44SJohn Forte evl_strip(ev); 326*fcf3ce44SJohn Forte /* if it is marked as a removed event, do not add it */ 327*fcf3ce44SJohn Forte if (evf_rem(ev) != 0) { 328*fcf3ce44SJohn Forte ev_free(ev); 329*fcf3ce44SJohn Forte goto add_done; 330*fcf3ce44SJohn Forte } 331*fcf3ce44SJohn Forte } 332*fcf3ce44SJohn Forte 333*fcf3ce44SJohn Forte /* get the index in the il */ 334*fcf3ce44SJohn Forte if (t == 0) { 335*fcf3ce44SJohn Forte t = ev_intval(ev); 336*fcf3ce44SJohn Forte /* not initialization time */ 337*fcf3ce44SJohn Forte if (evf_init(ev) || evf_again(ev)) { 338*fcf3ce44SJohn Forte t1 = get_stopwatch(evf_wakeup(ev)); 339*fcf3ce44SJohn Forte /* make il up to date */ 340*fcf3ce44SJohn Forte il_shift(t1); 341*fcf3ce44SJohn Forte /* avoid overflow */ 342*fcf3ce44SJohn Forte if (t1 >= INFINITY - t) { 343*fcf3ce44SJohn Forte /* the last second */ 344*fcf3ce44SJohn Forte t1 = INFINITY - t1 - 1; 345*fcf3ce44SJohn Forte } 346*fcf3ce44SJohn Forte } 347*fcf3ce44SJohn Forte t += t1; 348*fcf3ce44SJohn Forte } 349*fcf3ce44SJohn Forte i = (t - LB) / DT; 350*fcf3ce44SJohn Forte if (i >= DU) { 351*fcf3ce44SJohn Forte i = DU; 352*fcf3ce44SJohn Forte } else { 353*fcf3ce44SJohn Forte i = (i + icurr) % DU; 354*fcf3ce44SJohn Forte } 355*fcf3ce44SJohn Forte 356*fcf3ce44SJohn Forte /* find the right key */ 357*fcf3ce44SJohn Forte k = (il[i])->left; 358*fcf3ce44SJohn Forte while (k->time > t) { 359*fcf3ce44SJohn Forte k = k->left; 360*fcf3ce44SJohn Forte } 361*fcf3ce44SJohn Forte k = k->right; 362*fcf3ce44SJohn Forte 363*fcf3ce44SJohn Forte /* need to split */ 364*fcf3ce44SJohn Forte if (k->count == NLIM) { 365*fcf3ce44SJohn Forte /* insert a new key */ 366*fcf3ce44SJohn Forte y = (el_key_t *)malloc(sizeof (el_key_t)); 367*fcf3ce44SJohn Forte if (y == NULL) { 368*fcf3ce44SJohn Forte ec = ISNS_RSP_INTERNAL_ERROR; 369*fcf3ce44SJohn Forte goto add_done; 370*fcf3ce44SJohn Forte } 371*fcf3ce44SJohn Forte k->count = NLIM / 2; 372*fcf3ce44SJohn Forte x = k->notice; 373*fcf3ce44SJohn Forte for (j = 1; j <= NLIM / 2; j++) { 374*fcf3ce44SJohn Forte x = x->pred; 375*fcf3ce44SJohn Forte } 376*fcf3ce44SJohn Forte y->time = x->time; 377*fcf3ce44SJohn Forte y->count = NLIM - NLIM / 2; 378*fcf3ce44SJohn Forte y->notice = x; 379*fcf3ce44SJohn Forte y->right = k; 380*fcf3ce44SJohn Forte y->left = k->left; 381*fcf3ce44SJohn Forte k->left->right = y; 382*fcf3ce44SJohn Forte k->left = y; 383*fcf3ce44SJohn Forte 384*fcf3ce44SJohn Forte /* update the key */ 385*fcf3ce44SJohn Forte x->key = y; 386*fcf3ce44SJohn Forte 387*fcf3ce44SJohn Forte /* shift */ 388*fcf3ce44SJohn Forte if (y->time > t) { 389*fcf3ce44SJohn Forte k = y; 390*fcf3ce44SJohn Forte } 391*fcf3ce44SJohn Forte } 392*fcf3ce44SJohn Forte 393*fcf3ce44SJohn Forte /* make a new notice */ 394*fcf3ce44SJohn Forte x = (el_notice_t *)malloc(sizeof (el_notice_t)); 395*fcf3ce44SJohn Forte if (x == NULL) { 396*fcf3ce44SJohn Forte ec = ISNS_RSP_INTERNAL_ERROR; 397*fcf3ce44SJohn Forte goto add_done; 398*fcf3ce44SJohn Forte } 399*fcf3ce44SJohn Forte x->time = t; 400*fcf3ce44SJohn Forte x->event = ev; 401*fcf3ce44SJohn Forte x->isdummy = 0; 402*fcf3ce44SJohn Forte x->key = NULL; 403*fcf3ce44SJohn Forte 404*fcf3ce44SJohn Forte /* insert it */ 405*fcf3ce44SJohn Forte n = k->notice; 406*fcf3ce44SJohn Forte while (n->time > t) { 407*fcf3ce44SJohn Forte n = n->pred; 408*fcf3ce44SJohn Forte } 409*fcf3ce44SJohn Forte x->pred = n; 410*fcf3ce44SJohn Forte x->sucd = n->sucd; 411*fcf3ce44SJohn Forte n->sucd->pred = x; 412*fcf3ce44SJohn Forte n->sucd = x; 413*fcf3ce44SJohn Forte 414*fcf3ce44SJohn Forte /* increase number of notice */ 415*fcf3ce44SJohn Forte k->count ++; 416*fcf3ce44SJohn Forte 417*fcf3ce44SJohn Forte /* reset current notice and wake up idle */ 418*fcf3ce44SJohn Forte if (curr == NULL || curr->time > t) { 419*fcf3ce44SJohn Forte curr = x; 420*fcf3ce44SJohn Forte } 421*fcf3ce44SJohn Forte 422*fcf3ce44SJohn Forte /* clear event flags */ 423*fcf3ce44SJohn Forte evf_zero(ev); 424*fcf3ce44SJohn Forte 425*fcf3ce44SJohn Forte isnslog(LOG_DEBUG, "el_add", "%s [%d] is scheduled at %d.", 426*fcf3ce44SJohn Forte ((ev_t *)ev)->type == EV_ESI ? "ESI" : "REG_EXP", 427*fcf3ce44SJohn Forte ((ev_t *)ev)->uid, 428*fcf3ce44SJohn Forte t); 429*fcf3ce44SJohn Forte 430*fcf3ce44SJohn Forte add_done: 431*fcf3ce44SJohn Forte /* unlock the event set */ 432*fcf3ce44SJohn Forte (void) pthread_mutex_unlock(&el_mtx); 433*fcf3ce44SJohn Forte 434*fcf3ce44SJohn Forte /* failed, free it */ 435*fcf3ce44SJohn Forte if (ec != 0) { 436*fcf3ce44SJohn Forte ev_free(ev); 437*fcf3ce44SJohn Forte isnslog(LOG_DEBUG, "el_add", "failed, no memory."); 438*fcf3ce44SJohn Forte } 439*fcf3ce44SJohn Forte 440*fcf3ce44SJohn Forte return (ec); 441*fcf3ce44SJohn Forte } 442*fcf3ce44SJohn Forte 443*fcf3ce44SJohn Forte /* 444*fcf3ce44SJohn Forte * **************************************************************************** 445*fcf3ce44SJohn Forte * 446*fcf3ce44SJohn Forte * el_remove: 447*fcf3ce44SJohn Forte * Remove or update an event from the element list. If the event is 448*fcf3ce44SJohn Forte * currently not in the element list, it must be in a queue which 449*fcf3ce44SJohn Forte * contains all of event which are being executing at the moment. 450*fcf3ce44SJohn Forte * So it seeks the event from the list prior to the element list. 451*fcf3ce44SJohn Forte * 452*fcf3ce44SJohn Forte * id1 - The event ID. 453*fcf3ce44SJohn Forte * id2 - The second ID for the event update. 454*fcf3ce44SJohn Forte * pending - Do not actually remove, mark it for removal pending. 455*fcf3ce44SJohn Forte * return - Error code. 456*fcf3ce44SJohn Forte * 457*fcf3ce44SJohn Forte * **************************************************************************** 458*fcf3ce44SJohn Forte */ 459*fcf3ce44SJohn Forte int 460*fcf3ce44SJohn Forte el_remove( 461*fcf3ce44SJohn Forte uint32_t id1, 462*fcf3ce44SJohn Forte uint32_t id2, 463*fcf3ce44SJohn Forte int pending 464*fcf3ce44SJohn Forte ) 465*fcf3ce44SJohn Forte { 466*fcf3ce44SJohn Forte el_key_t *k, *kl, *kr; 467*fcf3ce44SJohn Forte el_notice_t *n, *n2; 468*fcf3ce44SJohn Forte 469*fcf3ce44SJohn Forte (void) pthread_mutex_lock(&el_mtx); 470*fcf3ce44SJohn Forte 471*fcf3ce44SJohn Forte /* search the event from the event list which is being handled */ 472*fcf3ce44SJohn Forte if (evl_remove(id1, id2, pending) != 0) { 473*fcf3ce44SJohn Forte (void) pthread_mutex_unlock(&el_mtx); 474*fcf3ce44SJohn Forte return (0); 475*fcf3ce44SJohn Forte } 476*fcf3ce44SJohn Forte 477*fcf3ce44SJohn Forte /* search the notice starting from current */ 478*fcf3ce44SJohn Forte n = curr; 479*fcf3ce44SJohn Forte while (n != NULL) { 480*fcf3ce44SJohn Forte /* found the match notice */ 481*fcf3ce44SJohn Forte if (!n->isdummy && ev_match(n->event, id1) != 0) { 482*fcf3ce44SJohn Forte if (ev_remove(n->event, id2, 1, pending) == 0) { 483*fcf3ce44SJohn Forte /* update the key of the match notice */ 484*fcf3ce44SJohn Forte k = n->key; 485*fcf3ce44SJohn Forte if (k != NULL && k->count == 1) { 486*fcf3ce44SJohn Forte /* no more notice */ 487*fcf3ce44SJohn Forte k->left->right = k->right; 488*fcf3ce44SJohn Forte k->right->left = k->left; 489*fcf3ce44SJohn Forte free(k); 490*fcf3ce44SJohn Forte } else { 491*fcf3ce44SJohn Forte if (k != NULL) { 492*fcf3ce44SJohn Forte k->notice = n->pred; 493*fcf3ce44SJohn Forte k->notice->key = k; 494*fcf3ce44SJohn Forte k->time = k->notice->time; 495*fcf3ce44SJohn Forte } 496*fcf3ce44SJohn Forte n2 = n; 497*fcf3ce44SJohn Forte k = n2->key; 498*fcf3ce44SJohn Forte while (k == NULL) { 499*fcf3ce44SJohn Forte n2 = n2->sucd; 500*fcf3ce44SJohn Forte k = n2->key; 501*fcf3ce44SJohn Forte } 502*fcf3ce44SJohn Forte /* decrease the count by one */ 503*fcf3ce44SJohn Forte k->count --; 504*fcf3ce44SJohn Forte /* merge the keys */ 505*fcf3ce44SJohn Forte kl = k->left; 506*fcf3ce44SJohn Forte kr = k->right; 507*fcf3ce44SJohn Forte if (!kl->notice->isdummy && 508*fcf3ce44SJohn Forte (kl->count + k->count) <= NLIM) { 509*fcf3ce44SJohn Forte /* delete the left key */ 510*fcf3ce44SJohn Forte k->count += kl->count; 511*fcf3ce44SJohn Forte k->left = kl->left; 512*fcf3ce44SJohn Forte k->left->right = k; 513*fcf3ce44SJohn Forte kl->notice->key = NULL; 514*fcf3ce44SJohn Forte free(kl); 515*fcf3ce44SJohn Forte } else if (!k->notice->isdummy && 516*fcf3ce44SJohn Forte (kr->count + k->count) <= NLIM) { 517*fcf3ce44SJohn Forte /* delete this key */ 518*fcf3ce44SJohn Forte kr->count += k->count; 519*fcf3ce44SJohn Forte kr->left = k->left; 520*fcf3ce44SJohn Forte kr->left->right = kr; 521*fcf3ce44SJohn Forte k->notice->key = NULL; 522*fcf3ce44SJohn Forte free(k); 523*fcf3ce44SJohn Forte } 524*fcf3ce44SJohn Forte } 525*fcf3ce44SJohn Forte /* delete the match notice */ 526*fcf3ce44SJohn Forte n->pred->sucd = n->sucd; 527*fcf3ce44SJohn Forte n->sucd->pred = n->pred; 528*fcf3ce44SJohn Forte /* update current */ 529*fcf3ce44SJohn Forte if (n == curr) { 530*fcf3ce44SJohn Forte n2 = n->sucd; 531*fcf3ce44SJohn Forte while (n2 != NULL && n2->isdummy) { 532*fcf3ce44SJohn Forte n2 = n2->sucd; 533*fcf3ce44SJohn Forte } 534*fcf3ce44SJohn Forte curr = n2; 535*fcf3ce44SJohn Forte } 536*fcf3ce44SJohn Forte free(n); 537*fcf3ce44SJohn Forte } 538*fcf3ce44SJohn Forte break; /* exit while loop */ 539*fcf3ce44SJohn Forte } 540*fcf3ce44SJohn Forte n = n->sucd; 541*fcf3ce44SJohn Forte } 542*fcf3ce44SJohn Forte 543*fcf3ce44SJohn Forte (void) pthread_mutex_unlock(&el_mtx); 544*fcf3ce44SJohn Forte 545*fcf3ce44SJohn Forte return (0); 546*fcf3ce44SJohn Forte } 547*fcf3ce44SJohn Forte 548*fcf3ce44SJohn Forte /* 549*fcf3ce44SJohn Forte * **************************************************************************** 550*fcf3ce44SJohn Forte * 551*fcf3ce44SJohn Forte * el_first: 552*fcf3ce44SJohn Forte * Fetch the first event from the element list. 553*fcf3ce44SJohn Forte * 554*fcf3ce44SJohn Forte * t - Pointer of time of the event for returning. 555*fcf3ce44SJohn Forte * return - The event. 556*fcf3ce44SJohn Forte * 557*fcf3ce44SJohn Forte * **************************************************************************** 558*fcf3ce44SJohn Forte */ 559*fcf3ce44SJohn Forte void * 560*fcf3ce44SJohn Forte el_first( 561*fcf3ce44SJohn Forte uint32_t *t 562*fcf3ce44SJohn Forte ) 563*fcf3ce44SJohn Forte { 564*fcf3ce44SJohn Forte void *p = NULL; 565*fcf3ce44SJohn Forte 566*fcf3ce44SJohn Forte el_notice_t *n; 567*fcf3ce44SJohn Forte el_key_t *k; 568*fcf3ce44SJohn Forte 569*fcf3ce44SJohn Forte (void) pthread_mutex_lock(&el_mtx); 570*fcf3ce44SJohn Forte 571*fcf3ce44SJohn Forte if (curr != NULL) { 572*fcf3ce44SJohn Forte /* remove current from the event set */ 573*fcf3ce44SJohn Forte curr->pred->sucd = curr->sucd; 574*fcf3ce44SJohn Forte curr->sucd->pred = curr->pred; 575*fcf3ce44SJohn Forte 576*fcf3ce44SJohn Forte /* decrease number of notice */ 577*fcf3ce44SJohn Forte n = curr; 578*fcf3ce44SJohn Forte while (n->key == NULL) { 579*fcf3ce44SJohn Forte n = n->sucd; 580*fcf3ce44SJohn Forte } 581*fcf3ce44SJohn Forte k = n->key; 582*fcf3ce44SJohn Forte k->count --; 583*fcf3ce44SJohn Forte 584*fcf3ce44SJohn Forte /* empty not-dummy key */ 585*fcf3ce44SJohn Forte if (k->count == 0) { 586*fcf3ce44SJohn Forte k->left->right = k->right; 587*fcf3ce44SJohn Forte k->right->left = k->left; 588*fcf3ce44SJohn Forte free(k); 589*fcf3ce44SJohn Forte } 590*fcf3ce44SJohn Forte 591*fcf3ce44SJohn Forte /* get next notice */ 592*fcf3ce44SJohn Forte n = curr->sucd; 593*fcf3ce44SJohn Forte while (n != NULL && n->isdummy) { 594*fcf3ce44SJohn Forte n = n->sucd; 595*fcf3ce44SJohn Forte } 596*fcf3ce44SJohn Forte 597*fcf3ce44SJohn Forte /* return the time */ 598*fcf3ce44SJohn Forte *t = curr->time; 599*fcf3ce44SJohn Forte /* reset current notice */ 600*fcf3ce44SJohn Forte p = curr->event; 601*fcf3ce44SJohn Forte free(curr); 602*fcf3ce44SJohn Forte curr = n; 603*fcf3ce44SJohn Forte } 604*fcf3ce44SJohn Forte 605*fcf3ce44SJohn Forte /* the one that is being handled by esi_proc */ 606*fcf3ce44SJohn Forte if (p) { 607*fcf3ce44SJohn Forte evl_append(p); 608*fcf3ce44SJohn Forte } 609*fcf3ce44SJohn Forte 610*fcf3ce44SJohn Forte (void) pthread_mutex_unlock(&el_mtx); 611*fcf3ce44SJohn Forte 612*fcf3ce44SJohn Forte if (p) { 613*fcf3ce44SJohn Forte isnslog(LOG_DEBUG, "el_first", "%s [%d] is fetched.", 614*fcf3ce44SJohn Forte ((ev_t *)p)->type == EV_ESI ? "ESI" : "REG_EXP", 615*fcf3ce44SJohn Forte ((ev_t *)p)->uid); 616*fcf3ce44SJohn Forte } 617*fcf3ce44SJohn Forte 618*fcf3ce44SJohn Forte return (p); 619*fcf3ce44SJohn Forte } 620