nid.h

00001 /*
00002  * $Id$
00003  *
00004  * nonce id and pool management (stuff common to nonce-count and one
00005  * time nonces)
00006  *
00007  * Copyright (C) 2008 iptelorg GmbH
00008  *
00009  * This file is part of ser, a free SIP server.
00010  *
00011  * ser is free software; you can redistribute it and/or modify
00012  * it under the terms of the GNU General Public License as published by
00013  * the Free Software Foundation; either version 2 of the License, or
00014  * (at your option) any later version
00015  *
00016  * ser is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License 
00022  * along with this program; if not, write to the Free Software 
00023  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024  */
00025 /*
00026  * Defines: 
00027  *  USE_NC, USE_OT_NONCE  - if neither of them defined no code will be 
00028  *                          compiled
00029  */
00030 /*
00031  * History:
00032  * --------
00033  * 2008-07-08  initial version (andrei)
00034  */
00035 
00036 #ifndef _nid_h
00037 #define _nid_h
00038 
00039 extern unsigned nid_pool_no; /* number of index pools */
00040 
00041 #if defined USE_NC || defined USE_OT_NONCE
00042 
00043 #include "../../atomic_ops.h"
00044 #include "../../pt.h" /* process_no */
00045 
00046 /* id incremenet, to avoid cacheline ping-pong and cover all the
00047  * array locations it should be a number prime with the array size and
00048  * bigger then the cacheline. Since this is used also for onetime nonces
00049  * => NID_INC/8 > CACHELINE
00050  * This number also limits the maximum pool/partition size, since the
00051  * id overflow check checks if crt_id - nonce_id >= partition_size*NID_INC
00052  * => maximum partition size is (nid_t)(-1)/NID_INC*/
00053 #define NID_INC 257
00054 
00055 #define DEFAULT_NID_POOL_SIZE 1
00056 #define MAX_NID_POOL_SIZE    64 /* max. 6 bits used for the pool no*/
00057 
00058 #define CACHELINE_SIZE 256 /* more then most real-word cachelines */
00059 
00060 /* if larger tables are needed (see NID_INC comments above), consider
00061  * switching to unsigned long long */
00062 typedef unsigned int nid_t;
00063 
00064 struct pool_index{
00065         atomic_t id;
00066         char pad[CACHELINE_SIZE-sizeof(atomic_t)];/* padding to cacheline size */
00067 };
00068 
00069 extern struct pool_index* nid_crt;
00070 
00071 
00072 /* instead of storing only the 2^k size we store also k
00073  * for faster operations */
00074 extern unsigned int nid_pool_k; /* pools no in bits (k in 2^k) */
00075 extern unsigned int nid_pool_mask; /* mask for computing the current pool*/
00076 
00077 int init_nonce_id();
00078 void destroy_nonce_id();
00079 
00080 
00081 /* get current index in pool p */
00082 #define nid_get(p) \
00083         atomic_get(&nid_crt[(p)].id)
00084 
00085 /* get pool for the current process */
00086 #define nid_get_pool()  (process_no & nid_pool_mask)
00087 
00088 /* inc the specified index and return its new value */
00089 #define nid_inc(pool) \
00090         ((nid_t)atomic_add(&nid_crt[(pool)].id, NID_INC))
00091 
00092 #endif /* #if defined USE_NC || defined USE_OT_NONCE */
00093 #endif /* _nid_h */