Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 712c4ba in mainline for kernel/generic/src/console/console.c


Ignore:
Timestamp:
2011-05-20T16:09:24Z (11 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master
Children:
b6f3e7e
Parents:
326bf65
Message:

avoid spinlocks to be taken in the direct code path to physically outputing kconsole characters to the framebuffer (this fixes ticket #243)
the spinlock in printf() (kernel) was sacrificed, this might lead potentially to scrambled kconsole output
the hack of ignoring spinlocks whose names start with "*" in the livelock detector can be removed

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/console/console.c

    r326bf65 r712c4ba  
    6060
    6161/** Kernel log initialized */
    62 static bool klog_inited = false;
     62static atomic_t klog_inited = {false};
    6363
    6464/** First kernel log characters */
     
    7575
    7676/** Kernel log spinlock */
    77 SPINLOCK_STATIC_INITIALIZE_NAME(klog_lock, "*klog_lock");
     77SPINLOCK_STATIC_INITIALIZE_NAME(klog_lock, "klog_lock");
    7878
    7979/** Physical memory area used for klog buffer */
     
    166166       
    167167        event_set_unmask_callback(EVENT_KLOG, klog_update);
    168        
    169         spinlock_lock(&klog_lock);
    170         klog_inited = true;
    171         spinlock_unlock(&klog_lock);
     168        atomic_set(&klog_inited, true);
    172169}
    173170
     
    264261void klog_update(void)
    265262{
     263        if (!atomic_get(&klog_inited))
     264                return;
     265       
    266266        spinlock_lock(&klog_lock);
    267267       
    268         if ((klog_inited) && (klog_uspace > 0)) {
     268        if (klog_uspace > 0) {
    269269                if (event_notify_3(EVENT_KLOG, true, klog_start, klog_len,
    270270                    klog_uspace) == EOK)
     
    277277void putchar(const wchar_t ch)
    278278{
     279        bool ordy = ((stdout) && (stdout->op->write));
     280       
    279281        spinlock_lock(&klog_lock);
    280282       
    281         if ((klog_stored > 0) && (stdout) && (stdout->op->write)) {
    282                 /* Print charaters stored in kernel log */
    283                 size_t i;
    284                 for (i = klog_len - klog_stored; i < klog_len; i++)
    285                         stdout->op->write(stdout, klog[(klog_start + i) % KLOG_LENGTH], silent);
    286                 klog_stored = 0;
     283        /* Print charaters stored in kernel log */
     284        if (ordy) {
     285                while (klog_stored > 0) {
     286                        wchar_t tmp = klog[(klog_start + klog_len - klog_stored) % KLOG_LENGTH];
     287                        klog_stored--;
     288                       
     289                        /*
     290                         * We need to give up the spinlock for
     291                         * the physical operation of writting out
     292                         * the character.
     293                         */
     294                        spinlock_unlock(&klog_lock);
     295                        stdout->op->write(stdout, tmp, silent);
     296                        spinlock_lock(&klog_lock);
     297                }
    287298        }
    288299       
     
    294305                klog_start = (klog_start + 1) % KLOG_LENGTH;
    295306       
    296         if ((stdout) && (stdout->op->write))
     307        if (!ordy) {
     308                if (klog_stored < klog_len)
     309                        klog_stored++;
     310        }
     311       
     312        /* The character is stored for uspace */
     313        if (klog_uspace < klog_len)
     314                klog_uspace++;
     315       
     316        spinlock_unlock(&klog_lock);
     317       
     318        if (ordy) {
     319                /*
     320                 * Output the character. In this case
     321                 * it should be no longer buffered.
     322                 */
    297323                stdout->op->write(stdout, ch, silent);
    298         else {
     324        } else {
    299325                /*
    300326                 * No standard output routine defined yet.
     
    306332                 * Note that the early_putc() function might be
    307333                 * a no-op on certain hardware configurations.
    308                  *
    309334                 */
    310335                early_putchar(ch);
    311                
    312                 if (klog_stored < klog_len)
    313                         klog_stored++;
    314         }
    315        
    316         /* The character is stored for uspace */
    317         if (klog_uspace < klog_len)
    318                 klog_uspace++;
    319        
    320         spinlock_unlock(&klog_lock);
     336        }
    321337       
    322338        /* Force notification on newline */
Note: See TracChangeset for help on using the changeset viewer.