/* FUNCTION: Video :: VideoThread ARGUMENTS: cookie RETURN: thread exit status DESCRIPTION: Video playback thread */ int32 Video :: VideoThread(void *cookie) { Video *video = (Video *) cookie; if (video->fVideoTrack == NULL) { exit_thread(B_ERROR); return B_ERROR; } float frames_per_second = (float)video->fVideoTrack->CountFrames() / (float)video->fVideoTrack->Duration() * 1000000.0f; bigtime_t frame_time = (bigtime_t) (1000000.0f / frames_per_second); video->fPerformanceTime = real_time_clock_usecs() + frame_time; status_t err = B_OK; printf("frame_rate = %f\n", frames_per_second); while (1) { err = video->ShowNextFrame(); bigtime_t zzz = video->fPerformanceTime - real_time_clock_usecs(); if (zzz < 0) zzz = 1; video->fPerformanceTime += frame_time; snooze(zzz); } exit_thread(err); return err; }
static size_t GetHighResClock(void *buf, size_t maxbytes) { bigtime_t bigtime; /* Actually a int64 */ bigtime = real_time_clock_usecs(); return CopyLowBits(buf, maxbytes, &bigtime, sizeof(bigtime)); }
status_t user_timer_get_clock(clockid_t clockID, bigtime_t& _time) { switch (clockID) { case CLOCK_MONOTONIC: _time = system_time(); return B_OK; case CLOCK_REALTIME: _time = real_time_clock_usecs(); return B_OK; case CLOCK_THREAD_CPUTIME_ID: { Thread* thread = thread_get_current_thread(); InterruptsSpinLocker timeLocker(thread->time_lock); _time = thread->CPUTime(false); return B_OK; } case CLOCK_PROCESS_USER_CPUTIME_ID: { Team* team = thread_get_current_thread()->team; InterruptsSpinLocker timeLocker(team->time_lock); _time = team->UserCPUTime(); return B_OK; } case CLOCK_PROCESS_CPUTIME_ID: default: { // get the ID of the target team (or the respective placeholder) team_id teamID; if (clockID == CLOCK_PROCESS_CPUTIME_ID) { teamID = B_CURRENT_TEAM; } else { if (clockID < 0) return B_BAD_VALUE; if (clockID == team_get_kernel_team_id()) return B_NOT_ALLOWED; teamID = clockID; } // get the team Team* team = Team::Get(teamID); if (team == NULL) return B_BAD_VALUE; BReference<Team> teamReference(team, true); // get the time InterruptsSpinLocker timeLocker(team->time_lock); _time = team->CPUTime(false); return B_OK; } } }
/* FUNCTION: ViewBook :: Render ARGUMENTS: none RETURN: n/a DESCRIPTION: Draw view contents */ void ViewBook :: Render(void) { LockGL(); bigtime_t current_time = real_time_clock_usecs(); bigtime_t delta = current_time - fStartTime; fStartTime = current_time; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // page freefall (gravity) if (!fMouseTracking && (fPageAngle > kPageMinAngle) && (fPageAngle < kPageMaxAngle)) { if (fPageAngle < 90) fPageAngle -= 30*(float)delta/1000000.0f; else fPageAngle += 30*(float)delta/1000000.0f; } fPages[PAGE_MIDDLE]->SetAngle(fPageAngle); // Draw pages glPushMatrix(); glTranslatef(-0.5f*kPageWidth, 0.5f*kPageHeight, 0); fPages[PAGE_MIDDLE]->Render(); glPopMatrix(); glPushMatrix(); glTranslatef(-0.5f*kPageWidth, 0.5f*kPageHeight, 0); fPages[PAGE_LEFT]->Render(); glPopMatrix(); glPushMatrix(); glTranslatef(-0.5f*kPageWidth, 0.5f*kPageHeight, 0); fPages[PAGE_RIGHT]->Render(); glPopMatrix(); glFlush(); SwapBuffers(); // Frame rate /* static int fps = 0; static int time_delta = 0; fps++; time_delta += delta; if (time_delta > 1000000) { printf("%d fps\n", fps); fps = 0; time_delta = 0; } */ UnlockGL(); }
/* FUNCTION: ViewCube :: ViewCube ARGUMENTS: frame RETURN: n/a DESCRIPTION: Constructor */ ViewCube :: ViewCube(BRect frame) : ViewObject(frame) { fStartTime = real_time_clock_usecs(); for (int i=0; i < NUMBER_FACES; i++) fMediaSources[i] = 0; fCube = 0; fSpeed = 10; fMouseTracking = false; }
int main(int argc, char** argv) { srand(real_time_clock_usecs()); status_t status; AppServer* server = new AppServer(&status); if (status == B_OK) server->Run(); return status == B_OK ? EXIT_SUCCESS : EXIT_FAILURE; }
/* FUNCTION: ViewBook :: ViewBook ARGUMENTS: frame RETURN: n/a DESCRIPTION: Constructor */ ViewBook :: ViewBook(BRect frame) : ViewObject(frame) { fStartTime = real_time_clock_usecs(); for (int i=0; i < NUMBER_SOURCES; i++) fMediaSources[i] = 0; for (int i=0; i < NUMBER_PAGES; i++) fPages[i] = 0; fMouseTracking = false; fPageAngle = kPageMaxAngle; }
int main(int argc, char** argv) { // There can be only one.... if (find_port(SERVER_PORT_NAME) >= B_OK) return -1; srand(real_time_clock_usecs()); AppServer* server = new AppServer; server->RunLooper(); return 0; }
void VolumeWatcher::Stop() { char name[255]; fVolume.GetName(name); // set the time before stop watching to not miss anything fVolumeWorker->SetWatchingPosition(real_time_clock_usecs()); stop_watching(&fWatchNameHandler); fVolumeWorker->WriteAnalyserSettings(); // don't stop the work because we have to handle all entries after writing // the watching position //fVolumeWorker->Stop(); fCatchUpManager.Stop(); }
bool VolumeWatcher::StartWatching() { Run(); watch_volume(fVolume.Device(), B_WATCH_NAME | B_WATCH_STAT, &fWatchNameHandler); // set the time after start watching to not miss anything fVolumeWorker->SetWatchingStart(real_time_clock_usecs()); char name[255]; fVolume.GetName(name); fCatchUpManager.CatchUp(); fWatching = true; return true; }
bigtime_t system_boot_time(void) { bigtime_t retValue = B_INT64_CONSTANT(-1); unix_boot_time_locker.Lock(); if (unix_boot_time >= B_INT64_CONSTANT(0)) { retValue = unix_boot_time; } else { struct timespec ts; if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { bigtime_t up_time = (int64)ts.tv_sec * SECS_TO_US + (int64)(ts.tv_nsec + 500) /B_INT64_CONSTANT(1000); retValue = unix_boot_time = real_time_clock_usecs() - up_time; } } unix_boot_time_locker.Unlock(); return retValue; }
/* AttributeDumper::AttributeDumper(node_ref* nref) { BDirectory *fDir = new BDirectory(nref); fNode = fDir; } */ AttributeDumper::AttributeDumper(entry_ref* ref,bool asdir){ fNode = NULL; //new name BString filename; filename << real_time_clock_usecs(); // BDirectory dir(ref); fPath.SetTo(&dir,NULL); fPath.Append(filename.String()); if(!asdir) { BFile *fFile = new BFile(fPath.Path(),B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); fNode = fFile; BNodeInfo(fNode).SetType(MIME_ITEM); get_ref_for_path(fPath.Path(),&fRef); } else { BDirectory *fDir = new BDirectory(dir); dir.CreateDirectory(fPath.Path(),fDir); fNode = fDir; BNodeInfo(fNode).SetType(MIME_CHANNEL); printf("New directory Path [%s]\n",fPath.Path()); get_ref_for_path(fPath.Path(),&fRef); } }
/* FUNCTION: ViewCube :: Render ARGUMENTS: none RETURN: n/a DESCRIPTION: Draw view contents */ void ViewCube :: Render(void) { LockGL(); bigtime_t current_time = real_time_clock_usecs(); bigtime_t delta = current_time - fStartTime; fStartTime = current_time; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); fCubeAngle += fSpeed*(float)delta/1000000.0f; fCube->SetAngle(0, 0, fCubeAngle); glPushMatrix(); glTranslatef(0.0f, 0.0f, 0.15f); fCube->Render(); glPopMatrix(); glFlush(); SwapBuffers(); // Display frame rate /* static int fps = 0; static int time_delta = 0; fps++; time_delta += delta; if (time_delta > 1000000) { printf("%d fps\n", fps); fps = 0; time_delta = 0; } */ UnlockGL(); }
status_t Inode::WriteAt(Transaction& transaction, off_t pos, const uint8* buffer, size_t* _length) { TRACE("Inode::WriteAt(%lld, %p, *(%p) = %ld)\n", pos, buffer, _length, *_length); ReadLocker readLocker(fLock); if (IsFileCacheDisabled()) return B_BAD_VALUE; if (pos < 0) return B_BAD_VALUE; readLocker.Unlock(); TRACE("Inode::WriteAt(): Starting transaction\n"); transaction.Start(fVolume->GetJournal()); WriteLocker writeLocker(fLock); TRACE("Inode::WriteAt(): Updating modification time\n"); struct timespec timespec; _BigtimeToTimespec(real_time_clock_usecs(), ×pec); SetModificationTime(×pec); // NOTE: Debugging info to find why sometimes resize doesn't happen size_t length = *_length; #ifdef TRACE_EXT2 off_t oldEnd = pos + length; TRACE("Inode::WriteAt(): Old calc for end? %x:%x\n", (int)(oldEnd >> 32), (int)(oldEnd & 0xFFFFFFFF)); #endif off_t end = pos + (off_t)length; off_t oldSize = Size(); TRACE("Inode::WriteAt(): Old size: %x:%x, new size: %x:%x\n", (int)(oldSize >> 32), (int)(oldSize & 0xFFFFFFFF), (int)(end >> 32), (int)(end & 0xFFFFFFFF)); if (end > oldSize) { status_t status = Resize(transaction, end); if (status != B_OK) { *_length = 0; WriteLockInTransaction(transaction); return status; } status = WriteBack(transaction); if (status != B_OK) { *_length = 0; WriteLockInTransaction(transaction); return status; } } writeLocker.Unlock(); if (oldSize < pos) FillGapWithZeros(oldSize, pos); if (length == 0) { // Probably just changed the file size with the pos parameter return B_OK; } TRACE("Inode::WriteAt(): Performing write: %p, %lld, %p, %ld\n", FileCache(), pos, buffer, *_length); status_t status = file_cache_write(FileCache(), NULL, pos, buffer, _length); WriteLockInTransaction(transaction); TRACE("Inode::WriteAt(): Done\n"); return status; }
void PanelView::MessageReceived(BMessage* message) //////////////////////////////////////////////////////////////////////// { switch(message->what) { case MSG_FILE_SEEK: SeekModeOn(); break; case MSG_SEEKING: SeekFor(m_SeekTextControl->Text()); break; case MSG_FILE_SEEK_END: SeekModeOff(); break; case PATH_MSG_CD_PARENT: GotoParent(); break; case PATH_MSG_CD_ROOT: GotoRoot(); break; case PATH_MSG_CD_HOME: GotoHome(); break; case PATH_MSG_CD_DESKTOP: GotoDesktop(); break; case PATH_MSG_CD_DISKS: if (m_SeekMode) SeekModeOff(); GotoDisks(); break; case MSG_FILELISTVIEW_SELECTION: SelectionChanged(); break; case MSG_PANEL_SELECTED: m_LastSelectionTime = real_time_clock_usecs(); Parent()->Looper()->PostMessage(new BMessage(MSG_UPDATEPANEL_SELECTION)); // To update Panels... if (m_SeekMode) SeekModeOff(); break; case MSG_ENTER: Execute(m_CustomListView->GetSelectedEntry(0)); break; case MSG_SPACE: Calculate(m_CustomListView->GetSelectedEntry(0)); break; case MSG_VIEW: // F3 View(); break; case MSG_EDIT: // F4 Edit(); break; case MSG_COPY: // F5 Copy(); break; case MSG_MOVE: Move(); break; case MSG_RENAME: // Shift + F6 Rename(); break; case MSG_MAKEDIR: // F7 MakeDir(); break; case MSG_DELETE: // F8/Del Delete(); break; case MSG_QUIT: // F10 be_app->PostMessage(B_QUIT_REQUESTED); break; case MSG_RELOAD: // Reload after MkDir, Copy, Move, Delete... { BString itemname; // If there is a given name, let's set the selector to it... if (message->FindString("ItemName",&itemname)==B_OK) Reload(itemname.String()); else Reload(); // Rescan(); } break; case PANELMENU_MSG_SHOWICONS: if (m_PanelMenu_ShowIcons->IsMarked()) { m_PanelMenu_ShowIcons->SetMarked(false); m_Setting_ShowIcons = false; Reload(); } else { m_PanelMenu_ShowIcons->SetMarked(true); m_Setting_ShowIcons = true; Reload(); } break; case B_NODE_MONITOR: { BEntry entry; int32 opcode; const char *name; entry_ref ref; node_ref nref; if (message->FindInt32("opcode", &opcode) == B_OK) { switch (opcode) { case B_ENTRY_CREATED: message->FindInt32("device", &ref.device); message->FindInt64("directory", &ref.directory); message->FindString("name", &name); ref.set_name(name); entry.SetTo(&ref); RescanCreated(&entry); break; case B_ENTRY_REMOVED: message->FindInt32("device", &nref.device); message->FindInt64("node", &nref.node); RescanRemoved(nref); break; case B_ENTRY_MOVED: // or renamed... message->FindInt32("device", &nref.device); message->FindInt64("node", &nref.node); RescanRemoved(nref); message->FindInt32("device", &ref.device); message->FindInt64("to directory", &ref.directory); message->FindString("name", &name); ref.set_name(name); entry.SetTo(&ref); RescanCreated(&entry); break; case B_STAT_CHANGED: message->FindInt32("device", &nref.device); message->FindInt64("node", &nref.node); RescanStat(nref); break; case B_ATTR_CHANGED: message->FindInt32("device", &nref.device); message->FindInt64("node", &nref.node); RescanAttr(nref); break; case B_DEVICE_MOUNTED: if (m_PanelMode==PM_DISKS) Reload(); break; case B_DEVICE_UNMOUNTED: if (m_PanelMode==PM_DISKS) Reload(); break; } } } break; default: BView::MessageReceived(message); } }
bigtime_t system_time(void) { // FIXME return(real_time_clock_usecs() - system_boot_time()); }
status_t ext2_write_stat(fs_volume* _volume, fs_vnode* _node, const struct stat* stat, uint32 mask) { TRACE("ext2_write_stat\n"); Volume* volume = (Volume*)_volume->private_volume; if (volume->IsReadOnly()) return B_READ_ONLY_DEVICE; Inode* inode = (Inode*)_node->private_node; ext2_inode& node = inode->Node(); bool updateTime = false; uid_t uid = geteuid(); bool isOwnerOrRoot = uid == 0 || uid == (uid_t)node.UserID(); bool hasWriteAccess = inode->CheckPermissions(W_OK) == B_OK; TRACE("ext2_write_stat: Starting transaction\n"); Transaction transaction(volume->GetJournal()); inode->WriteLockInTransaction(transaction); if ((mask & B_STAT_SIZE) != 0 && inode->Size() != stat->st_size) { if (inode->IsDirectory()) return B_IS_A_DIRECTORY; if (!inode->IsFile()) return B_BAD_VALUE; if (!hasWriteAccess) return B_NOT_ALLOWED; TRACE("ext2_write_stat: Old size: %ld, new size: %ld\n", (long)inode->Size(), (long)stat->st_size); off_t oldSize = inode->Size(); status_t status = inode->Resize(transaction, stat->st_size); if(status != B_OK) return status; if ((mask & B_STAT_SIZE_INSECURE) == 0) { rw_lock_write_unlock(inode->Lock()); inode->FillGapWithZeros(oldSize, inode->Size()); rw_lock_write_lock(inode->Lock()); } updateTime = true; } if ((mask & B_STAT_MODE) != 0) { // only the user or root can do that if (!isOwnerOrRoot) return B_NOT_ALLOWED; node.UpdateMode(stat->st_mode, S_IUMSK); updateTime = true; } if ((mask & B_STAT_UID) != 0) { // only root should be allowed if (uid != 0) return B_NOT_ALLOWED; node.SetUserID(stat->st_uid); updateTime = true; } if ((mask & B_STAT_GID) != 0) { // only the user or root can do that if (!isOwnerOrRoot) return B_NOT_ALLOWED; node.SetGroupID(stat->st_gid); updateTime = true; } if ((mask & B_STAT_MODIFICATION_TIME) != 0 || updateTime || (mask & B_STAT_CHANGE_TIME) != 0) { // the user or root can do that or any user with write access if (!isOwnerOrRoot && !hasWriteAccess) return B_NOT_ALLOWED; struct timespec newTimespec = { 0, 0}; if ((mask & B_STAT_MODIFICATION_TIME) != 0) newTimespec = stat->st_mtim; if ((mask & B_STAT_CHANGE_TIME) != 0 && stat->st_ctim.tv_sec > newTimespec.tv_sec) newTimespec = stat->st_ctim; if (newTimespec.tv_sec == 0) Inode::_BigtimeToTimespec(real_time_clock_usecs(), &newTimespec); inode->SetModificationTime(&newTimespec); } if ((mask & B_STAT_CREATION_TIME) != 0) { // the user or root can do that or any user with write access if (!isOwnerOrRoot && !hasWriteAccess) return B_NOT_ALLOWED; inode->SetCreationTime(&stat->st_crtim); } status_t status = inode->WriteBack(transaction); if (status == B_OK) status = transaction.Done(); if (status == B_OK) notify_stat_changed(volume->ID(), -1, inode->ID(), mask); return status; }
/*static*/ status_t Inode::Create(Transaction& transaction, Inode* parent, const char* name, int32 mode, int openMode, uint8 type, bool* _created, ino_t* _id, Inode** _inode, fs_vnode_ops* vnodeOps, uint32 publishFlags) { TRACE("Inode::Create()\n"); Volume* volume = transaction.GetVolume(); DirectoryIterator* entries = NULL; ObjectDeleter<DirectoryIterator> entriesDeleter; if (parent != NULL) { parent->WriteLockInTransaction(transaction); TRACE("Inode::Create(): Looking up entry destination\n"); HTree htree(volume, parent); status_t status = htree.Lookup(name, &entries); if (status == B_ENTRY_NOT_FOUND) { panic("We need to add the first node.\n"); return B_ERROR; } if (status != B_OK) return status; entriesDeleter.SetTo(entries); TRACE("Inode::Create(): Looking up to see if file already exists\n"); ino_t entryID; status = entries->FindEntry(name, &entryID); if (status == B_OK) { // File already exists TRACE("Inode::Create(): File already exists\n"); if (S_ISDIR(mode) || S_ISLNK(mode) || (openMode & O_EXCL) != 0) return B_FILE_EXISTS; Vnode vnode(volume, entryID); Inode* inode; status = vnode.Get(&inode); if (status != B_OK) { TRACE("Inode::Create() Failed to get the inode from the " "vnode\n"); return B_ENTRY_NOT_FOUND; } if (inode->IsDirectory() && (openMode & O_RWMASK) != O_RDONLY) return B_IS_A_DIRECTORY; if ((openMode & O_DIRECTORY) != 0 && !inode->IsDirectory()) return B_NOT_A_DIRECTORY; if (inode->CheckPermissions(open_mode_to_access(openMode) | ((openMode & O_TRUNC) != 0 ? W_OK : 0)) != B_OK) return B_NOT_ALLOWED; if ((openMode & O_TRUNC) != 0) { // Truncate requested TRACE("Inode::Create(): Truncating file\n"); inode->WriteLockInTransaction(transaction); status = inode->Resize(transaction, 0); if (status != B_OK) return status; } if (_created != NULL) *_created = false; if (_id != NULL) *_id = inode->ID(); if (_inode != NULL) *_inode = inode; if (_id != NULL || _inode != NULL) vnode.Keep(); TRACE("Inode::Create(): Done opening file\n"); return B_OK; /*} else if ((mode & S_ATTR_DIR) == 0) { TRACE("Inode::Create(): (mode & S_ATTR_DIR) == 0\n"); return B_BAD_VALUE;*/ } else if ((openMode & O_DIRECTORY) != 0) { TRACE("Inode::Create(): (openMode & O_DIRECTORY) != 0\n"); return B_ENTRY_NOT_FOUND; } // Return to initial position TRACE("Inode::Create(): Restarting iterator\n"); entries->Restart(); } status_t status; if (parent != NULL) { status = parent->CheckPermissions(W_OK); if (status != B_OK) return status; } TRACE("Inode::Create(): Allocating inode\n"); ino_t id; status = volume->AllocateInode(transaction, parent, mode, id); if (status != B_OK) { ERROR("Inode::Create(): AllocateInode() failed\n"); return status; } if (entries != NULL) { size_t nameLength = strlen(name); status = entries->AddEntry(transaction, name, nameLength, id, type); if (status != B_OK) { ERROR("Inode::Create(): AddEntry() failed\n"); return status; } } TRACE("Inode::Create(): Creating inode\n"); Inode* inode = new(std::nothrow) Inode(volume); if (inode == NULL) return B_NO_MEMORY; TRACE("Inode::Create(): Getting node structure\n"); ext2_inode& node = inode->Node(); TRACE("Inode::Create(): Initializing inode data\n"); memset(&node, 0, sizeof(ext2_inode)); node.SetMode(mode); node.SetUserID(geteuid()); node.SetGroupID(parent != NULL ? parent->Node().GroupID() : getegid()); node.SetNumLinks(inode->IsDirectory() ? 2 : 1); TRACE("Inode::Create(): Updating time\n"); struct timespec timespec; _BigtimeToTimespec(real_time_clock_usecs(), ×pec); inode->SetAccessTime(×pec); inode->SetCreationTime(×pec); inode->SetModificationTime(×pec); node.SetFlags(parent->Flags() & EXT2_INODE_INHERITED); if (volume->HasExtentsFeature() && (inode->IsDirectory() || inode->IsFile())) { node.SetFlag(EXT2_INODE_EXTENTS); ExtentStream stream(volume, &node.extent_stream, 0); stream.Init(); ASSERT(stream.Check()); } if (sizeof(ext2_inode) < volume->InodeSize()) node.SetExtraInodeSize(sizeof(ext2_inode) - EXT2_INODE_NORMAL_SIZE); TRACE("Inode::Create(): Updating ID\n"); inode->fID = id; if (inode->IsDirectory()) { TRACE("Inode::Create(): Initializing directory\n"); status = inode->InitDirectory(transaction, parent); if (status != B_OK) { ERROR("Inode::Create(): InitDirectory() failed\n"); delete inode; return status; } } // TODO: Maybe it can be better /*if (volume->HasExtendedAttributes()) { TRACE("Inode::Create(): Initializing extended attributes\n"); uint32 blockGroup = 0; uint32 pos = 0; uint32 allocated; status = volume->AllocateBlocks(transaction, 1, 1, blockGroup, pos, allocated); if (status != B_OK) return status; // Clear the new block uint32 blockNum = volume->FirstDataBlock() + pos + volume->BlocksPerGroup() * blockGroup; CachedBlock cached(volume); cached.SetToWritable(transaction, blockNum, true); node.SetExtendedAttributesBlock(blockNum); }*/ TRACE("Inode::Create(): Saving inode\n"); status = inode->WriteBack(transaction); if (status != B_OK) { delete inode; return status; } TRACE("Inode::Create(): Creating vnode\n"); Vnode vnode; status = vnode.Publish(transaction, inode, vnodeOps, publishFlags); if (status != B_OK) return status; if (!inode->IsSymLink()) { // Vnode::Publish doesn't publish symlinks if (!inode->IsDirectory()) { status = inode->EnableFileCache(); if (status != B_OK) return status; } inode->WriteLockInTransaction(transaction); } if (_created) *_created = true; if (_id != NULL) *_id = id; if (_inode != NULL) *_inode = inode; if (_id != NULL || _inode != NULL) vnode.Keep(); TRACE("Inode::Create(): Deleting entries iterator\n"); DirectoryIterator* iterator = entriesDeleter.Detach(); TRACE("Inode::Create(): Entries iterator: %p\n", entries); delete iterator; TRACE("Inode::Create(): Done\n"); return B_OK; }
/** * Wait for a date * * This function uses select() and an system date function to wake up at a * precise date. It should be used for process synchronization. If current date * is posterior to wished date, the function returns immediately. * \param date The date to wake up at */ void mwait( mtime_t date ) { #if defined( HAVE_KERNEL_OS_H ) mtime_t delay; delay = date - real_time_clock_usecs(); if( delay <= 0 ) { return; } snooze( delay ); #elif defined( WIN32 ) || defined( UNDER_CE ) mtime_t usec_time, delay; usec_time = mdate(); delay = date - usec_time; if( delay <= 0 ) { return; } msleep( delay ); #else struct timeval tv_date; mtime_t delay; /* delay in msec, signed to detect errors */ /* see mdate() about gettimeofday() possible errors */ gettimeofday( &tv_date, NULL ); /* calculate delay and check if current date is before wished date */ delay = date - (mtime_t) tv_date.tv_sec * 1000000 - (mtime_t) tv_date.tv_usec - 10000; /* Linux/i386 has a granularity of 10 ms. It's better to be in advance * than to be late. */ if( delay <= 0 ) /* wished date is now or already passed */ { return; } # if defined( PTH_INIT_IN_PTH_H ) pth_usleep( delay ); # elif defined( ST_INIT_IN_ST_H ) st_usleep( delay ); # else # if defined( HAVE_NANOSLEEP ) { struct timespec ts_delay; ts_delay.tv_sec = delay / 1000000; ts_delay.tv_nsec = (delay % 1000000) * 1000; nanosleep( &ts_delay, NULL ); } # else tv_date.tv_sec = delay / 1000000; tv_date.tv_usec = delay % 1000000; /* see msleep() about select() errors */ select( 0, NULL, NULL, NULL, &tv_date ); # endif # endif #endif }
/** * Return high precision date * * Uses the gettimeofday() function when possible (1 MHz resolution) or the * ftime() function (1 kHz resolution). */ mtime_t mdate( void ) { #if defined( HAVE_KERNEL_OS_H ) return( real_time_clock_usecs() ); #elif defined( WIN32 ) || defined( UNDER_CE ) /* We don't need the real date, just the value of a high precision timer */ static mtime_t freq = I64C(-1); mtime_t usec_time; if( freq == I64C(-1) ) { /* Extract from the Tcl source code: * (http://www.cs.man.ac.uk/fellowsd-bin/TIP/7.html) * * Some hardware abstraction layers use the CPU clock * in place of the real-time clock as a performance counter * reference. This results in: * - inconsistent results among the processors on * multi-processor systems. * - unpredictable changes in performance counter frequency * on "gearshift" processors such as Transmeta and * SpeedStep. * There seems to be no way to test whether the performance * counter is reliable, but a useful heuristic is that * if its frequency is 1.193182 MHz or 3.579545 MHz, it's * derived from a colorburst crystal and is therefore * the RTC rather than the TSC. If it's anything else, we * presume that the performance counter is unreliable. */ freq = ( QueryPerformanceFrequency( (LARGE_INTEGER *)&freq ) && (freq == I64C(1193182) || freq == I64C(3579545) ) ) ? freq : 0; } if( freq != 0 ) { /* Microsecond resolution */ QueryPerformanceCounter( (LARGE_INTEGER *)&usec_time ); return ( usec_time * 1000000 ) / freq; } else { /* Fallback on GetTickCount() which has a milisecond resolution * (actually, best case is about 10 ms resolution) * GetTickCount() only returns a DWORD thus will wrap after * about 49.7 days so we try to detect the wrapping. */ static CRITICAL_SECTION date_lock; static mtime_t i_previous_time = I64C(-1); static int i_wrap_counts = -1; if( i_wrap_counts == -1 ) { /* Initialization */ i_previous_time = I64C(1000) * GetTickCount(); InitializeCriticalSection( &date_lock ); i_wrap_counts = 0; } EnterCriticalSection( &date_lock ); usec_time = I64C(1000) * (i_wrap_counts * I64C(0x100000000) + GetTickCount()); if( i_previous_time > usec_time ) { /* Counter wrapped */ i_wrap_counts++; usec_time += I64C(0x100000000000); } i_previous_time = usec_time; LeaveCriticalSection( &date_lock ); return usec_time; } #else struct timeval tv_date; /* gettimeofday() could return an error, and should be tested. However, the * only possible error, according to 'man', is EFAULT, which can not happen * here, since tv is a local variable. */ gettimeofday( &tv_date, NULL ); return( (mtime_t) tv_date.tv_sec * 1000000 + (mtime_t) tv_date.tv_usec ); #endif }
/** * Return high precision date * * Use a 1 MHz clock when possible, or 1 kHz * * Beware ! It doesn't reflect the actual date (since epoch), but can be the machine's uptime or anything (when monotonic clock is used) */ mtime_t CoreAudioPlexSupport::mdate() { mtime_t res; #if defined (HAVE_CLOCK_NANOSLEEP) struct timespec ts; /* Try to use POSIX monotonic clock if available */ if( clock_gettime( CLOCK_MONOTONIC, &ts ) == EINVAL ) /* Run-time fallback to real-time clock (always available) */ (void)clock_gettime( CLOCK_REALTIME, &ts ); res = ((mtime_t)ts.tv_sec * (mtime_t)1000000) + (mtime_t)(ts.tv_nsec / 1000); #elif defined( HAVE_KERNEL_OS_H ) res = real_time_clock_usecs(); #elif defined( WIN32 ) || defined( UNDER_CE ) /* We don't need the real date, just the value of a high precision timer */ static mtime_t freq = INT64_C(-1); if( freq == INT64_C(-1) ) { /* Extract from the Tcl source code: * (http://www.cs.man.ac.uk/fellowsd-bin/TIP/7.html) * * Some hardware abstraction layers use the CPU clock * in place of the real-time clock as a performance counter * reference. This results in: * - inconsistent results among the processors on * multi-processor systems. * - unpredictable changes in performance counter frequency * on "gearshift" processors such as Transmeta and * SpeedStep. * There seems to be no way to test whether the performance * counter is reliable, but a useful heuristic is that * if its frequency is 1.193182 MHz or 3.579545 MHz, it's * derived from a colorburst crystal and is therefore * the RTC rather than the TSC. If it's anything else, we * presume that the performance counter is unreliable. */ LARGE_INTEGER buf; freq = ( QueryPerformanceFrequency( &buf ) && (buf.QuadPart == INT64_C(1193182) || buf.QuadPart == INT64_C(3579545) ) ) ? buf.QuadPart : 0; #if defined( WIN32 ) /* on windows 2000, XP and Vista detect if there are two cores there - that makes QueryPerformanceFrequency in any case not trustable? (may also be true, for single cores with adaptive CPU frequency and active power management?) */ HINSTANCE h_Kernel32 = LoadLibrary(_T("kernel32.dll")); if(h_Kernel32) { void WINAPI (*pf_GetSystemInfo)(LPSYSTEM_INFO); pf_GetSystemInfo = (void WINAPI (*)(LPSYSTEM_INFO)) GetProcAddress(h_Kernel32, _T("GetSystemInfo")); if(pf_GetSystemInfo) { SYSTEM_INFO system_info; pf_GetSystemInfo(&system_info); if(system_info.dwNumberOfProcessors > 1) freq = 0; } FreeLibrary(h_Kernel32); } #endif } if( freq != 0 ) { LARGE_INTEGER counter; QueryPerformanceCounter (&counter); /* Convert to from (1/freq) to microsecond resolution */ /* We need to split the division to avoid 63-bits overflow */ lldiv_t d = lldiv (counter.QuadPart, freq); res = (d.quot * 1000000) + ((d.rem * 1000000) / freq); } else { /* Fallback on timeGetTime() which has a millisecond resolution * (actually, best case is about 5 ms resolution) * timeGetTime() only returns a DWORD thus will wrap after * about 49.7 days so we try to detect the wrapping. */ static CRITICAL_SECTION date_lock; static mtime_t i_previous_time = INT64_C(-1); static int i_wrap_counts = -1; if( i_wrap_counts == -1 ) { /* Initialization */ #if defined( WIN32 ) i_previous_time = INT64_C(1000) * timeGetTime(); #else i_previous_time = INT64_C(1000) * GetTickCount(); #endif InitializeCriticalSection( &date_lock ); i_wrap_counts = 0; } EnterCriticalSection( &date_lock ); #if defined( WIN32 ) res = INT64_C(1000) * (i_wrap_counts * INT64_C(0x100000000) + timeGetTime()); #else res = INT64_C(1000) * (i_wrap_counts * INT64_C(0x100000000) + GetTickCount()); #endif if( i_previous_time > res ) { /* Counter wrapped */ i_wrap_counts++; res += INT64_C(0x100000000) * 1000; } i_previous_time = res; LeaveCriticalSection( &date_lock ); } #else struct timeval tv_date; /* gettimeofday() cannot fail given &tv_date is a valid address */ (void)gettimeofday( &tv_date, NULL ); res = (mtime_t) tv_date.tv_sec * 1000000 + (mtime_t) tv_date.tv_usec; #endif return res; }
status_t RunPipedCommand(const char *cmdstr, BString &out, bool redirectStdErr) { if (!cmdstr) return B_BAD_DATA; BString command(cmdstr); out = ""; if (gUsePipeHack) { BString tmpfilename("/tmp/Paladin.build.tmp."); tmpfilename << real_time_clock_usecs(); command << " > " << tmpfilename; if (redirectStdErr) command << " 2>&1"; system(command.String()); BFile file(tmpfilename.String(), B_READ_ONLY); if (file.InitCheck() != B_OK) { STRACE(1,("Couldn't make temporary file for RunPipedCommand(\"%s\")\n", command.String())); return file.InitCheck(); } // char buffer[1024]; // while (file.Read(buffer, 1024) > 0) // out << buffer; off_t fileSize; file.GetSize(&fileSize); char buffer[1028]; while (fileSize > 0) { size_t bytesRead = file.Read(buffer, fileSize > 1024 ? 1024 : fileSize); if (bytesRead <= 1024) buffer[bytesRead] = '\0'; out << buffer; fileSize -= bytesRead; } file.Unset(); BEntry(tmpfilename.String()).Remove(); } else { if (redirectStdErr) command << " 2>&1"; FILE *fd = popen(cmdstr,"r"); if (!fd) { STRACE(1,("Bailed out on RunPipedCommand(\"%s\"): NULL pipe descriptor\n", command.String())); return B_BUSTED_PIPE; } char buffer[1024]; BString errmsg; while (fgets(buffer,1024,fd)) out += buffer; pclose(fd); } return B_OK; }