kogmo_timestamp_t kogmo_timestamp_from_string (char *str) { kogmo_timestamp_t ts; int err; struct tm tmx; time_t secs; char ns_string[10]=""; char *ns_string_end; unsigned long int ns=0; int i; long long int lli; if ( str == NULL ) return 0; memset ( &tmx, 0, sizeof(struct tm)); ns = 0; err = sscanf ( str, "%d-%d-%d%*[ _tT]%d:%d:%d.%9s", &tmx.tm_year, &tmx.tm_mon , &tmx.tm_mday, &tmx.tm_hour, &tmx.tm_min, &tmx.tm_sec, ns_string ); // we need at least a date (time will be 00:00:00.0 then) if ( err < 3 ) { // for even more comfort, this also accepts times relative to now, // +/- followed by an offset in secondstimestamps (e.g. +12.3 or -7.25) if ( str[0] == '+' || str[0] == '-' ) { double off; err = sscanf ( str, "%lf", &off); if ( err != 1 ) return 0; ts = kogmo_timestamp_add_secs ( kogmo_timestamp_now (), off); return ts; } // for your comfort, this also accepts timestamps (>9999) err = sscanf ( str, "%lli", &lli); ts = (kogmo_timestamp_t) lli; if ( err != 1 || ts <= 9999) return 0; return ts; } // the ranges of those value are a horrible confusion, see mktime(3) tmx.tm_year -= 1900; tmx.tm_mon -= 1; tmx.tm_isdst = -1; secs = mktime (&tmx); if ( secs < 0 ) return 0; ns = strtoul(ns_string, &ns_string_end, 10); // calculate the correct decimal fraction (9 digits) // this is: ns *= pow ( 10, 9 - strlen (ns_string) ); // but prevent dependency from math-library for(i=ns_string_end-ns_string;i<9;i++) ns *= 10; ts = (kogmo_timestamp_t)ns + (kogmo_timestamp_t)secs * KOGMO_TIMESTAMP_TICKSPERSECOND; return ts; }
int kogmo_rtdb_objmeta_purge_objs (kogmo_rtdb_handle_t *db_h) { int i; kogmo_rtdb_obj_info_t *scan_objmeta_p; kogmo_rtdb_objid_t scan_oid; kogmo_timestamp_t ts,scan_delete_ts; int purge_keep_alloc = 0; int percent_free; CHK_DBH("kogmo_rtdb_objmeta_purge",db_h,0); percent_free = (float)db_h->localdata_p -> heap_free * 100 / db_h->localdata_p -> heap_size; #ifndef KOGMO_RTDB_HARDREALTIME if ( percent_free < KOGMO_RTDB_PURGE_KEEPALLOC_PERCFREE ) { DBG("purging preallocated memory, because only %i%% (<%i%%) is free", percent_free, KOGMO_RTDB_PURGE_KEEPALLOC_PERCFREE); purge_keep_alloc = 1; } #endif ts = kogmo_rtdb_timestamp_now(db_h); kogmo_rtdb_objmeta_lock(db_h); for(i=0;i<KOGMO_RTDB_OBJ_MAX;i++) { scan_objmeta_p = &db_h->localdata_p -> objmeta[i]; scan_oid = scan_objmeta_p->oid; scan_delete_ts = scan_objmeta_p -> deleted_ts; if (scan_oid && scan_delete_ts) { scan_delete_ts = kogmo_timestamp_add_secs( scan_delete_ts, scan_objmeta_p -> history_interval > db_h->localdata_p->default_keep_deleted_interval ? scan_objmeta_p -> history_interval : db_h->localdata_p->default_keep_deleted_interval); if ( scan_delete_ts < ts ) { if ( scan_objmeta_p->flags.keep_alloc && ( !purge_keep_alloc || kogmo_timestamp_diff_secs ( scan_delete_ts, ts ) < KOGMO_RTDB_PURGE_KEEPALLOC_MAXSECS) ) continue; // this is kept allocated and alloc-purce time is not reached or we do not purge kogmo_rtdb_obj_purgeslot(db_h, i); kogmo_rtdb_objmeta_unlock_notify(db_h); // give priority inheritance protocols a point to kick in kogmo_rtdb_objmeta_lock(db_h); } } } kogmo_rtdb_objmeta_unlock(db_h); percent_free = (float)db_h->localdata_p -> heap_free * 100 / db_h->localdata_p -> heap_size; DBG("purge: %i%% free (%lli/%lli)", percent_free, (long long int) db_h->localdata_p -> heap_free, (long long int) db_h->localdata_p -> heap_size); return 0; }